diff --git a/CHANGELOG.md b/CHANGELOG.md index c4a281acd..1627f39b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.21.4] - 2024-07-15 +- Removed pipeline deployment mode as CodeCommit is no longer accepting new repositories +- Cleaned up some issues around lambda layer building + ## [0.21.4] - 2024-07-15 - The Lex Web UI can now act as a passthrough for Q Business, allowing users to converse directly with their Q Business application while inheriting all the features of the Web UI such as embedding, CSS customizations and more. - Upgraded version of amazon-connect-chatjs diff --git a/README-connect-live-chat.md b/README-connect-live-chat.md index ff16e5a45..477f39dd6 100644 --- a/README-connect-live-chat.md +++ b/README-connect-live-chat.md @@ -80,32 +80,6 @@ messages to the user, set the ConnectWaitForAgentMessageIntervalInSeconds to 0. Once you have the parameters set, Create or update your stack. -### Using the pipeline template - -The pipeline templates setup a new pipeline and code commit repo which deploys LexWebUi. The master-pipeline.yaml -template can be used to create a new pipeline and kick off execution of the pipeline. For a new pipeline, the same -parameters described above can be specified. When complete, the newly deployed Lex Web Ui -will have an updated lex-web-ui-loader-config.json file containing all the values specified for Connect Live Chat. -Future modifications to connect live chat parameters should occur in the lex-web-ui-loader-config.json file and -then be committed to code commit repo for deployment. - -The new parameters configurable in lex-web-ui-loader-config.json are shown below. - -``` - "connect": { - "contactFlowId" : "YOUR CONTACT FLOW ID", - "instanceId" : "YOUR CONNECT INSTANCE ID", - "apiGatewayEndpoint" : "Your newly created Amazon API Gateway endpoint", - "promptForNameMessage": "Before starting a live chat, please tell me your name?", - "waitingForAgentMessage": "Thanks for waiting. An agent will be with you when available.", - "waitingForAgentMessageIntervalSeconds": 60, - "agentJoinedMessage": "{Agent} has joined.", - "agentLeftMessage": "{Agent} has left.", - "chatEndedMessage": "Chat ended.", - "attachChatTranscript": true - }, -``` - ## Usage Once the stack creation has completed, you can open the parent page hosting the Lex Web UI on your browser. diff --git a/README-css-style.md b/README-css-style.md index 55b47295e..e53635fd2 100644 --- a/README-css-style.md +++ b/README-css-style.md @@ -17,22 +17,7 @@ modifications outlined in this README. * Modify the CSS accordingly and save the file locally on your desktop * Upload the custom-chatbot-style.css back to your WebApp S3 bucket * Use the CloudFront console to invalidate the CloudFront distribution such that it will be served up immediately - -* CodePipeline/CodeBuild distribution - If you have used the master-pipeline.yaml to create a CodCommit/CodePipeline/CodeBuild distribution mechanism, - follow these steps. - * git clone the repo from CodeCommit - * Modify the CSS accordingly in your local repo - * Modify the root level Makefile and uncomment the lines noted below - ``` - # @echo "[INFO] copying custom-chatbot-style.css and setting cache max-age=0" - # aws s3 cp \ - # --metadata-directive REPLACE --cache-control max-age=0 \ - # "$(DIST_DIR)/custom-chatbot-style.css" s3://$(WEBAPP_BUCKET) - ``` - * Commit and push the changes to both files - * The resulting CodeBuild execution will publish the modified custom-chatbot-style.css to your WebApp S3 bucket. - + ## Summary of available css modifications ![Common use of CSS for LexWebUi](./img/LexWebUiStyle.png) diff --git a/README-qbusiness.md b/README-qbusiness.md index da4ab80a6..db272fdc6 100644 --- a/README-qbusiness.md +++ b/README-qbusiness.md @@ -12,7 +12,7 @@ This feature supports integration with file attachments, enable both to allow QB 1. An existing deployment of a Q Business application is required for this solution. Please reference the AWS docs for creating a new [Q Business application](https://docs.aws.amazon.com/amazonq/latest/qbusiness-ug/create-application.html) ### Deploy the Web UI -1. A deployment of the Lex Web UI with login enabled is required for Q Business integration. To launch a new +1. A deployment of the Lex Web UI with login enabled is required for Q Business integration. To launch a new deployment of the Web UI, go to the main [README](https://github.com/aws-samples/aws-lex-web-ui/blob/master/README.md) and select `Launch` for the region where your Q Business app is deployed. 2. The other bot fields for both V1 & V2 bots must be empty for the template to create the Q Business integration bot, please ensure that `Lex V1 Bot Configuration Parameters` and `Lex V2 Bot Configuration Parameters` are blank. @@ -69,4 +69,4 @@ This feature supports integration with file attachments, enable both to allow QB Your deployment of the Web UI should now talk directly to Amazon Q Business and return the same responses as the default web experience. In addition, by turning on upload capabilities you can ask Q Business questions about documents and get GenAI answers. - ![QBusinessDemo](./img//QBusiness.gif) \ No newline at end of file + ![QBusinessDemo](./img//QBusiness.gif) diff --git a/build/Makefile b/build/Makefile index 4944997c0..d7f07012b 100644 --- a/build/Makefile +++ b/build/Makefile @@ -21,8 +21,8 @@ VPATH := $(OUT) # upload files to bootstrap bucket # NOTE: files uploaded with public read permissions -upload: upload-templates upload-src-zip upload-response-card-image \ - upload-initiate-chat-lambda upload-streaming-lambda upload-qbusiness-lambda +upload: upload-templates upload-custom-resources-zip upload-src-zip upload-layers \ + upload-response-card-image upload-initiate-chat-lambda upload-streaming-lambda upload-qbusiness-lambda .PHONY: upload # create the output directory for tracking dependencies @@ -37,8 +37,42 @@ upload-templates: $(TEMPLATES) | $(OUT) aws s3 sync --acl public-read --exclude "*" --include "*.yaml" \ "$(TEMPLATES_DIR)" "s3://$(BOOTSTRAP_BUCKET_PATH)/templates/" \ | tee "$(OUT)/$(@)" + aws s3 cp "$(TEMPLATES_DIR)"/layers.zip \ + "s3://${BOOTSTRAP_BUCKET_PATH}/layers.zip" @echo "[INFO] master template: https://s3.amazonaws.com/$(BOOTSTRAP_BUCKET_PATH)/templates/master.yaml" +LAMBDA_LAYER_ZIP := $(TEMPLATES_DIR)/layers.zip + +upload-layers: + @echo "[INFO] Uploading lambda layer" + aws s3 cp --acl public-read "$(LAMBDA_LAYER_ZIP)" "s3://${BOOTSTRAP_BUCKET_PATH}/layers.zip" + +# cfn custom resource lambda files are found under this directory +CUSTOM_RESOURCES_DIR := $(TEMPLATES_DIR)/custom-resources + +# zip cfn custom resource lambda files +PY_MODULES := $(CUSTOM_RESOURCES_DIR)/py_modules +CUSTOM_RESOURCES_ZIP := custom-resources-$(VERSION).zip +CUSTOM_RESOURCES_FILES := $(wildcard $(CUSTOM_RESOURCES_DIR)/*.py) +CUSTOM_RESOURCES_FILES += $(PY_MODULES) +$(PY_MODULES): + pushd $(CUSTOM_RESOURCES_DIR) ; \ + [ -f requirements.txt ] && \ + python3 -m pip install --upgrade -r requirements.txt -t ./py_modules || true ; \ + popd ; +$(CUSTOM_RESOURCES_ZIP): $(CUSTOM_RESOURCES_FILES) | $(OUT) + @echo "[INFO] Creating custom resource Lambda zip file" + zip -u -j "$(OUT)/$(@)" $(?) ; \ + pushd $(CUSTOM_RESOURCES_DIR)/py_modules ; \ + zip -r -q "../../../build/$(OUT)/$(@)" . ; \ + popd ; +upload-custom-resources-zip: $(CUSTOM_RESOURCES_ZIP) | $(OUT) + @echo "[INFO] Uploading custom resources Lambda zip file" + aws s3 cp --acl public-read \ + "$(OUT)/$(CUSTOM_RESOURCES_ZIP)" \ + "s3://$(BOOTSTRAP_BUCKET_PATH)/$(CUSTOM_RESOURCES_ZIP)" \ + | tee -a "$(OUT)/$(@)" + # initiate chat lambda function INITIATE_CHAT_LAMBDA_DIR := $(SOURCE_DIR)/initiate-chat-lambda diff --git a/build/release.sh b/build/release.sh index 1c8405006..3b3b314d7 100755 --- a/build/release.sh +++ b/build/release.sh @@ -7,15 +7,10 @@ case $unamestr in "Darwin" | "FreeBSD") sed -i '' -e "s/(v.*)/($VERSION)/g" \ -e "s/Timestamp:.*/Timestamp: $timestamp/g" \ +-e "s/custom-resources-.*zip/custom-resources-$VERSION.zip/g" \ -e "s/src-.*zip/src-$VERSION.zip/g" \ -e "s/initiate-chat-lambda-.*zip/initiate-chat-lambda-$VERSION.zip/g" \ -../templates/master.yaml; - -sed -i '' -e "s/(v.*)/($VERSION)/g" \ --e "s/Timestamp:.*/Timestamp: $timestamp/g" \ --e "s/src-.*zip/src-$VERSION.zip/g" \ --e "s/initiate-chat-lambda-.*zip/initiate-chat-lambda-$VERSION.zip/g" \ -../templates/master-pipeline.yaml;; +../templates/master.yaml;; "Linux") sed -i -e "s/(v.*)/($VERSION)/g" \ @@ -23,16 +18,9 @@ sed -i -e "s/(v.*)/($VERSION)/g" \ -e "s/src-.*zip/src-$VERSION.zip/g" \ -e "s/initiate-chat-lambda-.*zip/initiate-chat-lambda-$VERSION.zip/g" \ -e "s/streaming-lambda-.*zip/streaming-lambda-$VERSION.zip/g" \ +-e "s/custom-resources-.*zip/custom-resources-$VERSION.zip/g" \ -e "s/qbusiness-lambda-.*zip/qbusiness-lambda-$VERSION.zip/g" \ -../templates/master.yaml; - -sed -i -e "s/(v.*)/($VERSION)/g" \ --e "s/Timestamp:.*/Timestamp: $timestamp/g" \ --e "s/src-.*zip/src-$VERSION.zip/g" \ --e "s/initiate-chat-lambda-.*zip/initiate-chat-lambda-$VERSION.zip/g" \ --e "s/streaming-lambda-.*zip/streaming-lambda-$VERSION.zip/g" \ --e "s/streaming-lambda-.*zip/qbusiness-lambda-$VERSION.zip/g" \ -../templates/master-pipeline.yaml;; +../templates/master.yaml;; *) sed -i -e "s/(v.*)/($VERSION)/g" \ @@ -40,17 +28,9 @@ sed -i -e "s/(v.*)/($VERSION)/g" \ -e "s/src-.*zip/src-$VERSION.zip/g" \ -e "s/initiate-chat-lambda-.*zip/initiate-chat-lambda-$VERSION.zip/g" \ -e "s/streaming-lambda-.*zip/streaming-lambda-$VERSION.zip/g" \ +-e "s/custom-resources-.*zip/custom-resources-$VERSION.zip/g" \ -e "s/qbusiness-lambda-.*zip/qbusiness-lambda-$VERSION.zip/g" \ -../templates/master.yaml; - -sed -i -e "s/(v.*)/($VERSION)/g" \ --e "s/Timestamp:.*/Timestamp: $timestamp/g" \ --e "s/src-.*zip/src-$VERSION.zip/g" \ --e "s/initiate-chat-lambda-.*zip/initiate-chat-lambda-$VERSION.zip/g" \ --e "s/streaming-lambda-.*zip/streaming-lambda-$VERSION.zip/g" \ --e "s/qbusiness-lambda-.*zip/qbusiness-lambda-$VERSION.zip/g" \ -../templates/master-pipeline.yaml;; - +../templates/master.yaml;; esac cd ../lex-web-ui @@ -59,6 +39,7 @@ npm run build-dist cd .. make cd build +make "custom-resources-$VERSION.zip" make "initiate-chat-lambda-$VERSION.zip" make "streaming-lambda-$VERSION.zip" make "qbusiness-lambda-$VERSION.zip" diff --git a/build/upload-bootstrap.sh b/build/upload-bootstrap.sh index 3cee82464..07c4b2596 100755 --- a/build/upload-bootstrap.sh +++ b/build/upload-bootstrap.sh @@ -26,6 +26,9 @@ popd aws s3 cp out/src-$version.zip \ "s3://${BOOTSTRAP_BUCKET_PATH}/src-$version.zip" +aws s3 cp out/custom-resources-$version.zip \ + "s3://${BOOTSTRAP_BUCKET_PATH}/custom-resources-$version.zip" + aws s3 cp out/initiate-chat-lambda-$version.zip \ "s3://${BOOTSTRAP_BUCKET_PATH}/initiate-chat-lambda-$version.zip" diff --git a/dist/lex-web-ui-loader.min.css b/dist/lex-web-ui-loader.min.css index 4aea88d68..d7349b62d 100644 --- a/dist/lex-web-ui-loader.min.css +++ b/dist/lex-web-ui-loader.min.css @@ -1,5 +1,5 @@ /*! -* lex-web-ui v0.21.4 +* lex-web-ui v0.21.5 * (c) 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Released under the Amazon Software License. */ diff --git a/dist/lex-web-ui-loader.min.js b/dist/lex-web-ui-loader.min.js index 4e335bea3..d65a34cbb 100644 --- a/dist/lex-web-ui-loader.min.js +++ b/dist/lex-web-ui-loader.min.js @@ -1,5 +1,5 @@ /*! -* lex-web-ui v0.21.4 +* lex-web-ui v0.21.5 * (c) 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Released under the Amazon Software License. */ diff --git a/dist/lex-web-ui.min.css b/dist/lex-web-ui.min.css index 6f70bbd80..b7a92b530 100644 --- a/dist/lex-web-ui.min.css +++ b/dist/lex-web-ui.min.css @@ -1,5 +1,5 @@ /*! -* lex-web-ui v0.21.4 +* lex-web-ui v0.21.5 * (c) 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Released under the Amazon Software License. */.min-button-content{border-radius:60px}.toolbar-color{background-color:#003da5!important}.nav-buttons{margin-left:8px!important;padding:0}.nav-button-prev{margin:0;padding:0}.localeInfo{margin-right:0;text-align:right;width:5em!important}.list .icon{height:20px;margin-right:8px;width:20px}.menu__content{border-radius:4px}.call-end{margin-left:5px;width:36px}.end-live-chat-btn{width:unset!important}.toolbar-image{margin-left:0!important;max-height:100%}.toolbar-title{width:max-content}.message-text[data-v-56991e33]{-webkit-hyphens:auto;hyphens:auto;overflow-wrap:break-word;padding:.8em;white-space:normal;width:100%;word-break:break-word}.message-text[data-v-56991e33] p{margin-bottom:16px}.sr-only{clip:rect(1px,1px,1px,1px)!important;border:0!important;clip-path:inset(50%)!important;height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.v-card[data-v-d2979826]{background-color:unset!important;box-shadow:none!important;padding-bottom:.5em;position:inherit;width:75vw}.card__title[data-v-d2979826]{padding:.75em .5em .5em}.card__text[data-v-d2979826]{padding:.33em}.button-row[data-v-d2979826]{display:inline-block}.v-card-actions .v-btn[data-v-d2979826]{font-size:1em;margin:4px;min-width:44px}.v-card-actions.button-row[data-v-d2979826]{justify-content:center;padding-bottom:.15em}.smicon[data-v-7a271702]{font-size:14px;margin-top:.75em}.message-bubble-column[data-v-7a271702],.message[data-v-7a271702]{flex:0 0 auto}.message-bubble-row-feedback[data-v-7a271702],.message-bubble-row-human[data-v-7a271702],.message[data-v-7a271702]{justify-content:flex-end}.message-bubble-row-bot[data-v-7a271702]{flex-wrap:nowrap;max-width:80vw}.message-date-feedback[data-v-7a271702],.message-date-human[data-v-7a271702]{text-align:right}.avatar[data-v-7a271702]{align-self:center;align-self:flex-start;border-radius:50%;margin-right:4px;min-height:calc(2.5em + 1.5vmin);min-width:calc(2.5em + 1.5vmin)}.message-bubble[data-v-7a271702]{align-self:center;border-radius:24px;display:inline-flex;font-size:calc(1em + .25vmin);padding:0 12px;width:-moz-fit-content;width:fit-content}.interactive-row[data-v-7a271702]{display:block}.focusable[data-v-7a271702]{box-shadow:0 .25px .75px #0000001f,0 .25px .5px #0000003d;cursor:default;transition:all .3s cubic-bezier(.25,.8,.25,1)}.focusable[data-v-7a271702]:focus{box-shadow:0 1.25px 3.75px #00000040,0 1.25px 2.5px #00000038;outline:none}.message-agent .message-bubble[data-v-7a271702],.message-bot .message-bubble[data-v-7a271702]{background-color:#ffebee}.message-feedback .message-bubble[data-v-7a271702],.message-human .message-bubble[data-v-7a271702]{background-color:#e8eaf6}.dialog-state[data-v-7a271702]{display:inline-flex}.dialog-state-ok[data-v-7a271702]{color:green}.dialog-state-fail[data-v-7a271702]{color:red}.play-icon[data-v-7a271702]{font-size:2em}.feedback-state[data-v-7a271702]{align-self:center;display:inline-flex}.feedback-icons-positive[data-v-7a271702]{color:grey;padding:.125em}.positiveClick[data-v-7a271702]{color:green;padding:.125em}.negativeClick[data-v-7a271702]{color:red;padding:.125em}.feedback-icons-positive[data-v-7a271702]:hover{color:green}.feedback-icons-negative[data-v-7a271702]{color:grey;padding-left:.2em}.feedback-icons-negative[data-v-7a271702]:hover{color:red}.copy-icon[data-v-7a271702]{align-self:center;display:inline-flex}.copy-icon[data-v-7a271702]:hover{color:grey}.response-card[data-v-7a271702]{justify-content:center;width:85vw}.no-point[data-v-7a271702]{pointer-events:none}.message-bubble-column[data-v-3f73af04],.message[data-v-3f73af04]{flex:0 0 auto}.message-bubble-row[data-v-3f73af04],.message[data-v-3f73af04]{max-width:80vw}.message-bubble[data-v-3f73af04]{align-self:center;border-radius:24px;display:inline-flex;font-size:calc(1em + .25vmin);padding:0 12px;width:-moz-fit-content;width:fit-content}.message-bot .message-bubble[data-v-3f73af04]{background-color:#ffebee}.message-list[data-v-f6e82dae]{overflow-x:hidden;overflow-y:auto;padding-top:1rem}.message-agent[data-v-f6e82dae],.message-bot[data-v-f6e82dae]{align-self:flex-start}.message-feedback[data-v-f6e82dae],.message-human[data-v-f6e82dae]{align-self:flex-end}.recorder-status[data-v-54f50400]{display:flex;flex:1;flex-direction:column}.status-text[data-v-54f50400]{align-self:center;display:flex;text-align:center}.volume-meter[data-v-54f50400]{display:flex}.volume-meter meter[data-v-54f50400]{display:flex;flex:1;height:.75rem}.audio-progress-bar[data-v-54f50400],.processing-bar[data-v-54f50400]{height:.75rem}.input-container{bottom:0;bottom:env(safe-area-inset-bottom);left:0;left:env(safe-area-inset-left);min-height:48px;position:fixed;right:0;right:env(safe-area-inset-right)}.toolbar-content{font-size:16px!important;padding-left:16px}.v-input{margin-bottom:10px}.message-list-container{background-color:#fefefe;position:fixed}.message-list-container.toolbar-height-sm{height:calc(100% - 112px);top:56px}.message-list-container.toolbar-height-md{height:calc(100% - 96px);top:48px}.message-list-container.toolbar-height-lg{height:calc(100% - 128px);top:64px}#lex-web[ui-minimized]{background:#0000}html{font-size:14px!important}@keyframes v-shake{59%{margin-left:0}60%,80%{margin-left:2px}70%,90%{margin-left:-2px}}.bg-black{background-color:#000!important;color:#fff!important}.bg-white{background-color:#fff!important;color:#000!important}.bg-transparent{background-color:initial!important;color:currentColor!important}.bg-red{background-color:#f44336!important;color:#fff!important}.bg-red-lighten-5{background-color:#ffebee!important;color:#000!important}.bg-red-lighten-4{background-color:#ffcdd2!important;color:#000!important}.bg-red-lighten-3{background-color:#ef9a9a!important;color:#000!important}.bg-red-lighten-2{background-color:#e57373!important;color:#fff!important}.bg-red-lighten-1{background-color:#ef5350!important;color:#fff!important}.bg-red-darken-1{background-color:#e53935!important;color:#fff!important}.bg-red-darken-2{background-color:#d32f2f!important;color:#fff!important}.bg-red-darken-3{background-color:#c62828!important;color:#fff!important}.bg-red-darken-4{background-color:#b71c1c!important;color:#fff!important}.bg-red-accent-1{background-color:#ff8a80!important;color:#000!important}.bg-red-accent-2{background-color:#ff5252!important;color:#fff!important}.bg-red-accent-3{background-color:#ff1744!important;color:#fff!important}.bg-red-accent-4{background-color:#d50000!important;color:#fff!important}.bg-pink{background-color:#e91e63!important;color:#fff!important}.bg-pink-lighten-5{background-color:#fce4ec!important;color:#000!important}.bg-pink-lighten-4{background-color:#f8bbd0!important;color:#000!important}.bg-pink-lighten-3{background-color:#f48fb1!important;color:#000!important}.bg-pink-lighten-2{background-color:#f06292!important;color:#fff!important}.bg-pink-lighten-1{background-color:#ec407a!important;color:#fff!important}.bg-pink-darken-1{background-color:#d81b60!important;color:#fff!important}.bg-pink-darken-2{background-color:#c2185b!important;color:#fff!important}.bg-pink-darken-3{background-color:#ad1457!important;color:#fff!important}.bg-pink-darken-4{background-color:#880e4f!important;color:#fff!important}.bg-pink-accent-1{background-color:#ff80ab!important;color:#fff!important}.bg-pink-accent-2{background-color:#ff4081!important;color:#fff!important}.bg-pink-accent-3{background-color:#f50057!important;color:#fff!important}.bg-pink-accent-4{background-color:#c51162!important;color:#fff!important}.bg-purple{background-color:#9c27b0!important;color:#fff!important}.bg-purple-lighten-5{background-color:#f3e5f5!important;color:#000!important}.bg-purple-lighten-4{background-color:#e1bee7!important;color:#000!important}.bg-purple-lighten-3{background-color:#ce93d8!important;color:#fff!important}.bg-purple-lighten-2{background-color:#ba68c8!important;color:#fff!important}.bg-purple-lighten-1{background-color:#ab47bc!important;color:#fff!important}.bg-purple-darken-1{background-color:#8e24aa!important;color:#fff!important}.bg-purple-darken-2{background-color:#7b1fa2!important;color:#fff!important}.bg-purple-darken-3{background-color:#6a1b9a!important;color:#fff!important}.bg-purple-darken-4{background-color:#4a148c!important;color:#fff!important}.bg-purple-accent-1{background-color:#ea80fc!important;color:#fff!important}.bg-purple-accent-2{background-color:#e040fb!important;color:#fff!important}.bg-purple-accent-3{background-color:#d500f9!important;color:#fff!important}.bg-purple-accent-4{background-color:#a0f!important;color:#fff!important}.bg-deep-purple{background-color:#673ab7!important;color:#fff!important}.bg-deep-purple-lighten-5{background-color:#ede7f6!important;color:#000!important}.bg-deep-purple-lighten-4{background-color:#d1c4e9!important;color:#000!important}.bg-deep-purple-lighten-3{background-color:#b39ddb!important;color:#fff!important}.bg-deep-purple-lighten-2{background-color:#9575cd!important;color:#fff!important}.bg-deep-purple-lighten-1{background-color:#7e57c2!important;color:#fff!important}.bg-deep-purple-darken-1{background-color:#5e35b1!important;color:#fff!important}.bg-deep-purple-darken-2{background-color:#512da8!important;color:#fff!important}.bg-deep-purple-darken-3{background-color:#4527a0!important;color:#fff!important}.bg-deep-purple-darken-4{background-color:#311b92!important;color:#fff!important}.bg-deep-purple-accent-1{background-color:#b388ff!important;color:#fff!important}.bg-deep-purple-accent-2{background-color:#7c4dff!important;color:#fff!important}.bg-deep-purple-accent-3{background-color:#651fff!important;color:#fff!important}.bg-deep-purple-accent-4{background-color:#6200ea!important;color:#fff!important}.bg-indigo{background-color:#3f51b5!important;color:#fff!important}.bg-indigo-lighten-5{background-color:#e8eaf6!important;color:#000!important}.bg-indigo-lighten-4{background-color:#c5cae9!important;color:#000!important}.bg-indigo-lighten-3{background-color:#9fa8da!important;color:#fff!important}.bg-indigo-lighten-2{background-color:#7986cb!important;color:#fff!important}.bg-indigo-lighten-1{background-color:#5c6bc0!important;color:#fff!important}.bg-indigo-darken-1{background-color:#3949ab!important;color:#fff!important}.bg-indigo-darken-2{background-color:#303f9f!important;color:#fff!important}.bg-indigo-darken-3{background-color:#283593!important;color:#fff!important}.bg-indigo-darken-4{background-color:#1a237e!important;color:#fff!important}.bg-indigo-accent-1{background-color:#8c9eff!important;color:#fff!important}.bg-indigo-accent-2{background-color:#536dfe!important;color:#fff!important}.bg-indigo-accent-3{background-color:#3d5afe!important;color:#fff!important}.bg-indigo-accent-4{background-color:#304ffe!important;color:#fff!important}.bg-blue{background-color:#2196f3!important;color:#fff!important}.bg-blue-lighten-5{background-color:#e3f2fd!important;color:#000!important}.bg-blue-lighten-4{background-color:#bbdefb!important;color:#000!important}.bg-blue-lighten-3{background-color:#90caf9!important;color:#000!important}.bg-blue-lighten-2{background-color:#64b5f6!important;color:#000!important}.bg-blue-lighten-1{background-color:#42a5f5!important;color:#fff!important}.bg-blue-darken-1{background-color:#1e88e5!important;color:#fff!important}.bg-blue-darken-2{background-color:#1976d2!important;color:#fff!important}.bg-blue-darken-3{background-color:#1565c0!important;color:#fff!important}.bg-blue-darken-4{background-color:#0d47a1!important;color:#fff!important}.bg-blue-accent-1{background-color:#82b1ff!important;color:#000!important}.bg-blue-accent-2{background-color:#448aff!important;color:#fff!important}.bg-blue-accent-3{background-color:#2979ff!important;color:#fff!important}.bg-blue-accent-4{background-color:#2962ff!important;color:#fff!important}.bg-light-blue{background-color:#03a9f4!important;color:#fff!important}.bg-light-blue-lighten-5{background-color:#e1f5fe!important;color:#000!important}.bg-light-blue-lighten-4{background-color:#b3e5fc!important;color:#000!important}.bg-light-blue-lighten-3{background-color:#81d4fa!important;color:#000!important}.bg-light-blue-lighten-2{background-color:#4fc3f7!important;color:#000!important}.bg-light-blue-lighten-1{background-color:#29b6f6!important;color:#000!important}.bg-light-blue-darken-1{background-color:#039be5!important;color:#fff!important}.bg-light-blue-darken-2{background-color:#0288d1!important;color:#fff!important}.bg-light-blue-darken-3{background-color:#0277bd!important;color:#fff!important}.bg-light-blue-darken-4{background-color:#01579b!important;color:#fff!important}.bg-light-blue-accent-1{background-color:#80d8ff!important;color:#000!important}.bg-light-blue-accent-2{background-color:#40c4ff!important;color:#000!important}.bg-light-blue-accent-3{background-color:#00b0ff!important;color:#fff!important}.bg-light-blue-accent-4{background-color:#0091ea!important;color:#fff!important}.bg-cyan{background-color:#00bcd4!important;color:#000!important}.bg-cyan-lighten-5{background-color:#e0f7fa!important;color:#000!important}.bg-cyan-lighten-4{background-color:#b2ebf2!important;color:#000!important}.bg-cyan-lighten-3{background-color:#80deea!important;color:#000!important}.bg-cyan-lighten-2{background-color:#4dd0e1!important;color:#000!important}.bg-cyan-lighten-1{background-color:#26c6da!important;color:#000!important}.bg-cyan-darken-1{background-color:#00acc1!important;color:#fff!important}.bg-cyan-darken-2{background-color:#0097a7!important;color:#fff!important}.bg-cyan-darken-3{background-color:#00838f!important;color:#fff!important}.bg-cyan-darken-4{background-color:#006064!important;color:#fff!important}.bg-cyan-accent-1{background-color:#84ffff!important;color:#000!important}.bg-cyan-accent-2{background-color:#18ffff!important;color:#000!important}.bg-cyan-accent-3{background-color:#00e5ff!important;color:#000!important}.bg-cyan-accent-4{background-color:#00b8d4!important;color:#fff!important}.bg-teal{background-color:#009688!important;color:#fff!important}.bg-teal-lighten-5{background-color:#e0f2f1!important;color:#000!important}.bg-teal-lighten-4{background-color:#b2dfdb!important;color:#000!important}.bg-teal-lighten-3{background-color:#80cbc4!important;color:#000!important}.bg-teal-lighten-2{background-color:#4db6ac!important;color:#fff!important}.bg-teal-lighten-1{background-color:#26a69a!important;color:#fff!important}.bg-teal-darken-1{background-color:#00897b!important;color:#fff!important}.bg-teal-darken-2{background-color:#00796b!important;color:#fff!important}.bg-teal-darken-3{background-color:#00695c!important;color:#fff!important}.bg-teal-darken-4{background-color:#004d40!important;color:#fff!important}.bg-teal-accent-1{background-color:#a7ffeb!important;color:#000!important}.bg-teal-accent-2{background-color:#64ffda!important;color:#000!important}.bg-teal-accent-3{background-color:#1de9b6!important;color:#000!important}.bg-teal-accent-4{background-color:#00bfa5!important;color:#fff!important}.bg-green{background-color:#4caf50!important;color:#fff!important}.bg-green-lighten-5{background-color:#e8f5e9!important;color:#000!important}.bg-green-lighten-4{background-color:#c8e6c9!important;color:#000!important}.bg-green-lighten-3{background-color:#a5d6a7!important;color:#000!important}.bg-green-lighten-2{background-color:#81c784!important;color:#000!important}.bg-green-lighten-1{background-color:#66bb6a!important;color:#fff!important}.bg-green-darken-1{background-color:#43a047!important;color:#fff!important}.bg-green-darken-2{background-color:#388e3c!important;color:#fff!important}.bg-green-darken-3{background-color:#2e7d32!important;color:#fff!important}.bg-green-darken-4{background-color:#1b5e20!important;color:#fff!important}.bg-green-accent-1{background-color:#b9f6ca!important;color:#000!important}.bg-green-accent-2{background-color:#69f0ae!important;color:#000!important}.bg-green-accent-3{background-color:#00e676!important;color:#000!important}.bg-green-accent-4{background-color:#00c853!important;color:#000!important}.bg-light-green{background-color:#8bc34a!important;color:#000!important}.bg-light-green-lighten-5{background-color:#f1f8e9!important;color:#000!important}.bg-light-green-lighten-4{background-color:#dcedc8!important;color:#000!important}.bg-light-green-lighten-3{background-color:#c5e1a5!important;color:#000!important}.bg-light-green-lighten-2{background-color:#aed581!important;color:#000!important}.bg-light-green-lighten-1{background-color:#9ccc65!important;color:#000!important}.bg-light-green-darken-1{background-color:#7cb342!important;color:#fff!important}.bg-light-green-darken-2{background-color:#689f38!important;color:#fff!important}.bg-light-green-darken-3{background-color:#558b2f!important;color:#fff!important}.bg-light-green-darken-4{background-color:#33691e!important;color:#fff!important}.bg-light-green-accent-1{background-color:#ccff90!important;color:#000!important}.bg-light-green-accent-2{background-color:#b2ff59!important;color:#000!important}.bg-light-green-accent-3{background-color:#76ff03!important;color:#000!important}.bg-light-green-accent-4{background-color:#64dd17!important;color:#000!important}.bg-lime{background-color:#cddc39!important;color:#000!important}.bg-lime-lighten-5{background-color:#f9fbe7!important;color:#000!important}.bg-lime-lighten-4{background-color:#f0f4c3!important;color:#000!important}.bg-lime-lighten-3{background-color:#e6ee9c!important;color:#000!important}.bg-lime-lighten-2{background-color:#dce775!important;color:#000!important}.bg-lime-lighten-1{background-color:#d4e157!important;color:#000!important}.bg-lime-darken-1{background-color:#c0ca33!important;color:#000!important}.bg-lime-darken-2{background-color:#afb42b!important;color:#000!important}.bg-lime-darken-3{background-color:#9e9d24!important;color:#fff!important}.bg-lime-darken-4{background-color:#827717!important;color:#fff!important}.bg-lime-accent-1{background-color:#f4ff81!important;color:#000!important}.bg-lime-accent-2{background-color:#eeff41!important;color:#000!important}.bg-lime-accent-3{background-color:#c6ff00!important;color:#000!important}.bg-lime-accent-4{background-color:#aeea00!important;color:#000!important}.bg-yellow{background-color:#ffeb3b!important;color:#000!important}.bg-yellow-lighten-5{background-color:#fffde7!important;color:#000!important}.bg-yellow-lighten-4{background-color:#fff9c4!important;color:#000!important}.bg-yellow-lighten-3{background-color:#fff59d!important;color:#000!important}.bg-yellow-lighten-2{background-color:#fff176!important;color:#000!important}.bg-yellow-lighten-1{background-color:#ffee58!important;color:#000!important}.bg-yellow-darken-1{background-color:#fdd835!important;color:#000!important}.bg-yellow-darken-2{background-color:#fbc02d!important;color:#000!important}.bg-yellow-darken-3{background-color:#f9a825!important;color:#000!important}.bg-yellow-darken-4{background-color:#f57f17!important;color:#fff!important}.bg-yellow-accent-1{background-color:#ffff8d!important;color:#000!important}.bg-yellow-accent-2{background-color:#ff0!important;color:#000!important}.bg-yellow-accent-3{background-color:#ffea00!important;color:#000!important}.bg-yellow-accent-4{background-color:#ffd600!important;color:#000!important}.bg-amber{background-color:#ffc107!important;color:#000!important}.bg-amber-lighten-5{background-color:#fff8e1!important;color:#000!important}.bg-amber-lighten-4{background-color:#ffecb3!important;color:#000!important}.bg-amber-lighten-3{background-color:#ffe082!important;color:#000!important}.bg-amber-lighten-2{background-color:#ffd54f!important;color:#000!important}.bg-amber-lighten-1{background-color:#ffca28!important;color:#000!important}.bg-amber-darken-1{background-color:#ffb300!important;color:#000!important}.bg-amber-darken-2{background-color:#ffa000!important;color:#000!important}.bg-amber-darken-3{background-color:#ff8f00!important;color:#000!important}.bg-amber-darken-4{background-color:#ff6f00!important;color:#fff!important}.bg-amber-accent-1{background-color:#ffe57f!important;color:#000!important}.bg-amber-accent-2{background-color:#ffd740!important;color:#000!important}.bg-amber-accent-3{background-color:#ffc400!important;color:#000!important}.bg-amber-accent-4{background-color:#ffab00!important;color:#000!important}.bg-orange{background-color:#ff9800!important;color:#000!important}.bg-orange-lighten-5{background-color:#fff3e0!important;color:#000!important}.bg-orange-lighten-4{background-color:#ffe0b2!important;color:#000!important}.bg-orange-lighten-3{background-color:#ffcc80!important;color:#000!important}.bg-orange-lighten-2{background-color:#ffb74d!important;color:#000!important}.bg-orange-lighten-1{background-color:#ffa726!important;color:#000!important}.bg-orange-darken-1{background-color:#fb8c00!important;color:#fff!important}.bg-orange-darken-2{background-color:#f57c00!important;color:#fff!important}.bg-orange-darken-3{background-color:#ef6c00!important;color:#fff!important}.bg-orange-darken-4{background-color:#e65100!important;color:#fff!important}.bg-orange-accent-1{background-color:#ffd180!important;color:#000!important}.bg-orange-accent-2{background-color:#ffab40!important;color:#000!important}.bg-orange-accent-3{background-color:#ff9100!important;color:#000!important}.bg-orange-accent-4{background-color:#ff6d00!important;color:#fff!important}.bg-deep-orange{background-color:#ff5722!important;color:#fff!important}.bg-deep-orange-lighten-5{background-color:#fbe9e7!important;color:#000!important}.bg-deep-orange-lighten-4{background-color:#ffccbc!important;color:#000!important}.bg-deep-orange-lighten-3{background-color:#ffab91!important;color:#000!important}.bg-deep-orange-lighten-2{background-color:#ff8a65!important;color:#000!important}.bg-deep-orange-lighten-1{background-color:#ff7043!important;color:#fff!important}.bg-deep-orange-darken-1{background-color:#f4511e!important;color:#fff!important}.bg-deep-orange-darken-2{background-color:#e64a19!important;color:#fff!important}.bg-deep-orange-darken-3{background-color:#d84315!important;color:#fff!important}.bg-deep-orange-darken-4{background-color:#bf360c!important;color:#fff!important}.bg-deep-orange-accent-1{background-color:#ff9e80!important;color:#000!important}.bg-deep-orange-accent-2{background-color:#ff6e40!important;color:#fff!important}.bg-deep-orange-accent-3{background-color:#ff3d00!important;color:#fff!important}.bg-deep-orange-accent-4{background-color:#dd2c00!important;color:#fff!important}.bg-brown{background-color:#795548!important;color:#fff!important}.bg-brown-lighten-5{background-color:#efebe9!important;color:#000!important}.bg-brown-lighten-4{background-color:#d7ccc8!important;color:#000!important}.bg-brown-lighten-3{background-color:#bcaaa4!important;color:#000!important}.bg-brown-lighten-2{background-color:#a1887f!important;color:#fff!important}.bg-brown-lighten-1{background-color:#8d6e63!important;color:#fff!important}.bg-brown-darken-1{background-color:#6d4c41!important;color:#fff!important}.bg-brown-darken-2{background-color:#5d4037!important;color:#fff!important}.bg-brown-darken-3{background-color:#4e342e!important;color:#fff!important}.bg-brown-darken-4{background-color:#3e2723!important;color:#fff!important}.bg-blue-grey{background-color:#607d8b!important;color:#fff!important}.bg-blue-grey-lighten-5{background-color:#eceff1!important;color:#000!important}.bg-blue-grey-lighten-4{background-color:#cfd8dc!important;color:#000!important}.bg-blue-grey-lighten-3{background-color:#b0bec5!important;color:#000!important}.bg-blue-grey-lighten-2{background-color:#90a4ae!important;color:#fff!important}.bg-blue-grey-lighten-1{background-color:#78909c!important;color:#fff!important}.bg-blue-grey-darken-1{background-color:#546e7a!important;color:#fff!important}.bg-blue-grey-darken-2{background-color:#455a64!important;color:#fff!important}.bg-blue-grey-darken-3{background-color:#37474f!important;color:#fff!important}.bg-blue-grey-darken-4{background-color:#263238!important;color:#fff!important}.bg-grey{background-color:#9e9e9e!important;color:#fff!important}.bg-grey-lighten-5{background-color:#fafafa!important;color:#000!important}.bg-grey-lighten-4{background-color:#f5f5f5!important;color:#000!important}.bg-grey-lighten-3{background-color:#eee!important;color:#000!important}.bg-grey-lighten-2{background-color:#e0e0e0!important;color:#000!important}.bg-grey-lighten-1{background-color:#bdbdbd!important;color:#000!important}.bg-grey-darken-1{background-color:#757575!important;color:#fff!important}.bg-grey-darken-2{background-color:#616161!important;color:#fff!important}.bg-grey-darken-3{background-color:#424242!important;color:#fff!important}.bg-grey-darken-4{background-color:#212121!important;color:#fff!important}.bg-shades-black{background-color:#000!important;color:#fff!important}.bg-shades-white{background-color:#fff!important;color:#000!important}.bg-shades-transparent{background-color:initial!important;color:currentColor!important}.text-black{color:#000!important}.text-white{color:#fff!important}.text-transparent{color:#0000!important}.text-red{color:#f44336!important}.text-red-lighten-5{color:#ffebee!important}.text-red-lighten-4{color:#ffcdd2!important}.text-red-lighten-3{color:#ef9a9a!important}.text-red-lighten-2{color:#e57373!important}.text-red-lighten-1{color:#ef5350!important}.text-red-darken-1{color:#e53935!important}.text-red-darken-2{color:#d32f2f!important}.text-red-darken-3{color:#c62828!important}.text-red-darken-4{color:#b71c1c!important}.text-red-accent-1{color:#ff8a80!important}.text-red-accent-2{color:#ff5252!important}.text-red-accent-3{color:#ff1744!important}.text-red-accent-4{color:#d50000!important}.text-pink{color:#e91e63!important}.text-pink-lighten-5{color:#fce4ec!important}.text-pink-lighten-4{color:#f8bbd0!important}.text-pink-lighten-3{color:#f48fb1!important}.text-pink-lighten-2{color:#f06292!important}.text-pink-lighten-1{color:#ec407a!important}.text-pink-darken-1{color:#d81b60!important}.text-pink-darken-2{color:#c2185b!important}.text-pink-darken-3{color:#ad1457!important}.text-pink-darken-4{color:#880e4f!important}.text-pink-accent-1{color:#ff80ab!important}.text-pink-accent-2{color:#ff4081!important}.text-pink-accent-3{color:#f50057!important}.text-pink-accent-4{color:#c51162!important}.text-purple{color:#9c27b0!important}.text-purple-lighten-5{color:#f3e5f5!important}.text-purple-lighten-4{color:#e1bee7!important}.text-purple-lighten-3{color:#ce93d8!important}.text-purple-lighten-2{color:#ba68c8!important}.text-purple-lighten-1{color:#ab47bc!important}.text-purple-darken-1{color:#8e24aa!important}.text-purple-darken-2{color:#7b1fa2!important}.text-purple-darken-3{color:#6a1b9a!important}.text-purple-darken-4{color:#4a148c!important}.text-purple-accent-1{color:#ea80fc!important}.text-purple-accent-2{color:#e040fb!important}.text-purple-accent-3{color:#d500f9!important}.text-purple-accent-4{color:#a0f!important}.text-deep-purple{color:#673ab7!important}.text-deep-purple-lighten-5{color:#ede7f6!important}.text-deep-purple-lighten-4{color:#d1c4e9!important}.text-deep-purple-lighten-3{color:#b39ddb!important}.text-deep-purple-lighten-2{color:#9575cd!important}.text-deep-purple-lighten-1{color:#7e57c2!important}.text-deep-purple-darken-1{color:#5e35b1!important}.text-deep-purple-darken-2{color:#512da8!important}.text-deep-purple-darken-3{color:#4527a0!important}.text-deep-purple-darken-4{color:#311b92!important}.text-deep-purple-accent-1{color:#b388ff!important}.text-deep-purple-accent-2{color:#7c4dff!important}.text-deep-purple-accent-3{color:#651fff!important}.text-deep-purple-accent-4{color:#6200ea!important}.text-indigo{color:#3f51b5!important}.text-indigo-lighten-5{color:#e8eaf6!important}.text-indigo-lighten-4{color:#c5cae9!important}.text-indigo-lighten-3{color:#9fa8da!important}.text-indigo-lighten-2{color:#7986cb!important}.text-indigo-lighten-1{color:#5c6bc0!important}.text-indigo-darken-1{color:#3949ab!important}.text-indigo-darken-2{color:#303f9f!important}.text-indigo-darken-3{color:#283593!important}.text-indigo-darken-4{color:#1a237e!important}.text-indigo-accent-1{color:#8c9eff!important}.text-indigo-accent-2{color:#536dfe!important}.text-indigo-accent-3{color:#3d5afe!important}.text-indigo-accent-4{color:#304ffe!important}.text-blue{color:#2196f3!important}.text-blue-lighten-5{color:#e3f2fd!important}.text-blue-lighten-4{color:#bbdefb!important}.text-blue-lighten-3{color:#90caf9!important}.text-blue-lighten-2{color:#64b5f6!important}.text-blue-lighten-1{color:#42a5f5!important}.text-blue-darken-1{color:#1e88e5!important}.text-blue-darken-2{color:#1976d2!important}.text-blue-darken-3{color:#1565c0!important}.text-blue-darken-4{color:#0d47a1!important}.text-blue-accent-1{color:#82b1ff!important}.text-blue-accent-2{color:#448aff!important}.text-blue-accent-3{color:#2979ff!important}.text-blue-accent-4{color:#2962ff!important}.text-light-blue{color:#03a9f4!important}.text-light-blue-lighten-5{color:#e1f5fe!important}.text-light-blue-lighten-4{color:#b3e5fc!important}.text-light-blue-lighten-3{color:#81d4fa!important}.text-light-blue-lighten-2{color:#4fc3f7!important}.text-light-blue-lighten-1{color:#29b6f6!important}.text-light-blue-darken-1{color:#039be5!important}.text-light-blue-darken-2{color:#0288d1!important}.text-light-blue-darken-3{color:#0277bd!important}.text-light-blue-darken-4{color:#01579b!important}.text-light-blue-accent-1{color:#80d8ff!important}.text-light-blue-accent-2{color:#40c4ff!important}.text-light-blue-accent-3{color:#00b0ff!important}.text-light-blue-accent-4{color:#0091ea!important}.text-cyan{color:#00bcd4!important}.text-cyan-lighten-5{color:#e0f7fa!important}.text-cyan-lighten-4{color:#b2ebf2!important}.text-cyan-lighten-3{color:#80deea!important}.text-cyan-lighten-2{color:#4dd0e1!important}.text-cyan-lighten-1{color:#26c6da!important}.text-cyan-darken-1{color:#00acc1!important}.text-cyan-darken-2{color:#0097a7!important}.text-cyan-darken-3{color:#00838f!important}.text-cyan-darken-4{color:#006064!important}.text-cyan-accent-1{color:#84ffff!important}.text-cyan-accent-2{color:#18ffff!important}.text-cyan-accent-3{color:#00e5ff!important}.text-cyan-accent-4{color:#00b8d4!important}.text-teal{color:#009688!important}.text-teal-lighten-5{color:#e0f2f1!important}.text-teal-lighten-4{color:#b2dfdb!important}.text-teal-lighten-3{color:#80cbc4!important}.text-teal-lighten-2{color:#4db6ac!important}.text-teal-lighten-1{color:#26a69a!important}.text-teal-darken-1{color:#00897b!important}.text-teal-darken-2{color:#00796b!important}.text-teal-darken-3{color:#00695c!important}.text-teal-darken-4{color:#004d40!important}.text-teal-accent-1{color:#a7ffeb!important}.text-teal-accent-2{color:#64ffda!important}.text-teal-accent-3{color:#1de9b6!important}.text-teal-accent-4{color:#00bfa5!important}.text-green{color:#4caf50!important}.text-green-lighten-5{color:#e8f5e9!important}.text-green-lighten-4{color:#c8e6c9!important}.text-green-lighten-3{color:#a5d6a7!important}.text-green-lighten-2{color:#81c784!important}.text-green-lighten-1{color:#66bb6a!important}.text-green-darken-1{color:#43a047!important}.text-green-darken-2{color:#388e3c!important}.text-green-darken-3{color:#2e7d32!important}.text-green-darken-4{color:#1b5e20!important}.text-green-accent-1{color:#b9f6ca!important}.text-green-accent-2{color:#69f0ae!important}.text-green-accent-3{color:#00e676!important}.text-green-accent-4{color:#00c853!important}.text-light-green{color:#8bc34a!important}.text-light-green-lighten-5{color:#f1f8e9!important}.text-light-green-lighten-4{color:#dcedc8!important}.text-light-green-lighten-3{color:#c5e1a5!important}.text-light-green-lighten-2{color:#aed581!important}.text-light-green-lighten-1{color:#9ccc65!important}.text-light-green-darken-1{color:#7cb342!important}.text-light-green-darken-2{color:#689f38!important}.text-light-green-darken-3{color:#558b2f!important}.text-light-green-darken-4{color:#33691e!important}.text-light-green-accent-1{color:#ccff90!important}.text-light-green-accent-2{color:#b2ff59!important}.text-light-green-accent-3{color:#76ff03!important}.text-light-green-accent-4{color:#64dd17!important}.text-lime{color:#cddc39!important}.text-lime-lighten-5{color:#f9fbe7!important}.text-lime-lighten-4{color:#f0f4c3!important}.text-lime-lighten-3{color:#e6ee9c!important}.text-lime-lighten-2{color:#dce775!important}.text-lime-lighten-1{color:#d4e157!important}.text-lime-darken-1{color:#c0ca33!important}.text-lime-darken-2{color:#afb42b!important}.text-lime-darken-3{color:#9e9d24!important}.text-lime-darken-4{color:#827717!important}.text-lime-accent-1{color:#f4ff81!important}.text-lime-accent-2{color:#eeff41!important}.text-lime-accent-3{color:#c6ff00!important}.text-lime-accent-4{color:#aeea00!important}.text-yellow{color:#ffeb3b!important}.text-yellow-lighten-5{color:#fffde7!important}.text-yellow-lighten-4{color:#fff9c4!important}.text-yellow-lighten-3{color:#fff59d!important}.text-yellow-lighten-2{color:#fff176!important}.text-yellow-lighten-1{color:#ffee58!important}.text-yellow-darken-1{color:#fdd835!important}.text-yellow-darken-2{color:#fbc02d!important}.text-yellow-darken-3{color:#f9a825!important}.text-yellow-darken-4{color:#f57f17!important}.text-yellow-accent-1{color:#ffff8d!important}.text-yellow-accent-2{color:#ff0!important}.text-yellow-accent-3{color:#ffea00!important}.text-yellow-accent-4{color:#ffd600!important}.text-amber{color:#ffc107!important}.text-amber-lighten-5{color:#fff8e1!important}.text-amber-lighten-4{color:#ffecb3!important}.text-amber-lighten-3{color:#ffe082!important}.text-amber-lighten-2{color:#ffd54f!important}.text-amber-lighten-1{color:#ffca28!important}.text-amber-darken-1{color:#ffb300!important}.text-amber-darken-2{color:#ffa000!important}.text-amber-darken-3{color:#ff8f00!important}.text-amber-darken-4{color:#ff6f00!important}.text-amber-accent-1{color:#ffe57f!important}.text-amber-accent-2{color:#ffd740!important}.text-amber-accent-3{color:#ffc400!important}.text-amber-accent-4{color:#ffab00!important}.text-orange{color:#ff9800!important}.text-orange-lighten-5{color:#fff3e0!important}.text-orange-lighten-4{color:#ffe0b2!important}.text-orange-lighten-3{color:#ffcc80!important}.text-orange-lighten-2{color:#ffb74d!important}.text-orange-lighten-1{color:#ffa726!important}.text-orange-darken-1{color:#fb8c00!important}.text-orange-darken-2{color:#f57c00!important}.text-orange-darken-3{color:#ef6c00!important}.text-orange-darken-4{color:#e65100!important}.text-orange-accent-1{color:#ffd180!important}.text-orange-accent-2{color:#ffab40!important}.text-orange-accent-3{color:#ff9100!important}.text-orange-accent-4{color:#ff6d00!important}.text-deep-orange{color:#ff5722!important}.text-deep-orange-lighten-5{color:#fbe9e7!important}.text-deep-orange-lighten-4{color:#ffccbc!important}.text-deep-orange-lighten-3{color:#ffab91!important}.text-deep-orange-lighten-2{color:#ff8a65!important}.text-deep-orange-lighten-1{color:#ff7043!important}.text-deep-orange-darken-1{color:#f4511e!important}.text-deep-orange-darken-2{color:#e64a19!important}.text-deep-orange-darken-3{color:#d84315!important}.text-deep-orange-darken-4{color:#bf360c!important}.text-deep-orange-accent-1{color:#ff9e80!important}.text-deep-orange-accent-2{color:#ff6e40!important}.text-deep-orange-accent-3{color:#ff3d00!important}.text-deep-orange-accent-4{color:#dd2c00!important}.text-brown{color:#795548!important}.text-brown-lighten-5{color:#efebe9!important}.text-brown-lighten-4{color:#d7ccc8!important}.text-brown-lighten-3{color:#bcaaa4!important}.text-brown-lighten-2{color:#a1887f!important}.text-brown-lighten-1{color:#8d6e63!important}.text-brown-darken-1{color:#6d4c41!important}.text-brown-darken-2{color:#5d4037!important}.text-brown-darken-3{color:#4e342e!important}.text-brown-darken-4{color:#3e2723!important}.text-blue-grey{color:#607d8b!important}.text-blue-grey-lighten-5{color:#eceff1!important}.text-blue-grey-lighten-4{color:#cfd8dc!important}.text-blue-grey-lighten-3{color:#b0bec5!important}.text-blue-grey-lighten-2{color:#90a4ae!important}.text-blue-grey-lighten-1{color:#78909c!important}.text-blue-grey-darken-1{color:#546e7a!important}.text-blue-grey-darken-2{color:#455a64!important}.text-blue-grey-darken-3{color:#37474f!important}.text-blue-grey-darken-4{color:#263238!important}.text-grey{color:#9e9e9e!important}.text-grey-lighten-5{color:#fafafa!important}.text-grey-lighten-4{color:#f5f5f5!important}.text-grey-lighten-3{color:#eee!important}.text-grey-lighten-2{color:#e0e0e0!important}.text-grey-lighten-1{color:#bdbdbd!important}.text-grey-darken-1{color:#757575!important}.text-grey-darken-2{color:#616161!important}.text-grey-darken-3{color:#424242!important}.text-grey-darken-4{color:#212121!important}.text-shades-black{color:#000!important}.text-shades-white{color:#fff!important}.text-shades-transparent{color:#0000!important} diff --git a/dist/wav-worker.js b/dist/wav-worker.js index 4208d6f30..23680c6c6 100644 --- a/dist/wav-worker.js +++ b/dist/wav-worker.js @@ -1,5 +1,5 @@ /*! -* lex-web-ui v0.21.4 +* lex-web-ui v0.21.5 * (c) 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Released under the Amazon Software License. */ diff --git a/dist/wav-worker.min.js b/dist/wav-worker.min.js index 542843ed5..0abfd3b0b 100644 --- a/dist/wav-worker.min.js +++ b/dist/wav-worker.min.js @@ -1,5 +1,5 @@ /*! -* lex-web-ui v0.21.4 +* lex-web-ui v0.21.5 * (c) 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Released under the Amazon Software License. */(()=>{var t={9306:(t,r,e)=>{"use strict";var n=e(4901),o=e(6823),i=TypeError;t.exports=function(t){if(n(t))return t;throw new i(o(t)+" is not a function")}},3506:(t,r,e)=>{"use strict";var n=e(3925),o=String,i=TypeError;t.exports=function(t){if(n(t))return t;throw new i("Can't set "+o(t)+" as a prototype")}},8551:(t,r,e)=>{"use strict";var n=e(34),o=String,i=TypeError;t.exports=function(t){if(n(t))return t;throw new i(o(t)+" is not an object")}},7811:t=>{"use strict";t.exports="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof DataView},7394:(t,r,e)=>{"use strict";var n=e(6706),o=e(4576),i=TypeError;t.exports=n(ArrayBuffer.prototype,"byteLength","get")||function(t){if("ArrayBuffer"!==o(t))throw new i("ArrayBuffer expected");return t.byteLength}},3238:(t,r,e)=>{"use strict";var n=e(9504),o=e(7394),i=n(ArrayBuffer.prototype.slice);t.exports=function(t){if(0!==o(t))return!1;try{return i(t,0,0),!1}catch(r){return!0}}},5636:(t,r,e)=>{"use strict";var n=e(4475),o=e(9504),i=e(6706),s=e(7696),u=e(3238),a=e(7394),c=e(4483),f=e(1548),p=n.structuredClone,y=n.ArrayBuffer,l=n.DataView,v=n.TypeError,h=Math.min,g=y.prototype,d=l.prototype,b=o(g.slice),x=i(g,"resizable","get"),w=i(g,"maxByteLength","get"),m=o(d.getInt8),A=o(d.setInt8);t.exports=(f||c)&&function(t,r,e){var n,o=a(t),i=void 0===r?o:s(r),g=!x||!x(t);if(u(t))throw new v("ArrayBuffer is detached");if(f&&(t=p(t,{transfer:[t]}),o===i&&(e||g)))return t;if(o>=i&&(!e||g))n=b(t,0,i);else{var d=e&&!g&&w?{maxByteLength:w(t)}:void 0;n=new y(i,d);for(var O=new l(t),T=new l(n),j=h(i,o),S=0;S{"use strict";var n,o,i,s=e(7811),u=e(3724),a=e(4475),c=e(4901),f=e(34),p=e(9297),y=e(6955),l=e(6823),v=e(6699),h=e(6840),g=e(2106),d=e(1625),b=e(2787),x=e(2967),w=e(8227),m=e(3392),A=e(1181),O=A.enforce,T=A.get,j=a.Int8Array,S=j&&j.prototype,E=a.Uint8ClampedArray,P=E&&E.prototype,C=j&&b(j),B=S&&b(S),M=Object.prototype,_=a.TypeError,I=w("toStringTag"),U=m("TYPED_ARRAY_TAG"),k="TypedArrayConstructor",F=s&&!!x&&"Opera"!==y(a.opera),R=!1,D={Int8Array:1,Uint8Array:1,Uint8ClampedArray:1,Int16Array:2,Uint16Array:2,Int32Array:4,Uint32Array:4,Float32Array:4,Float64Array:8},L={BigInt64Array:8,BigUint64Array:8},z=function(t){if(!f(t))return!1;var r=y(t);return"DataView"===r||p(D,r)||p(L,r)},V=function(t){var r=b(t);if(f(r)){var e=T(r);return e&&p(e,k)?e[k]:V(r)}},N=function(t){if(!f(t))return!1;var r=y(t);return p(D,r)||p(L,r)},q=function(t){if(N(t))return t;throw new _("Target is not a typed array")},W=function(t){if(c(t)&&(!x||d(C,t)))return t;throw new _(l(t)+" is not a typed array constructor")},Y=function(t,r,e,n){if(u){if(e)for(var o in D){var i=a[o];if(i&&p(i.prototype,t))try{delete i.prototype[t]}catch(s){try{i.prototype[t]=r}catch(c){}}}B[t]&&!e||h(B,t,e?r:F&&S[t]||r,n)}},G=function(t,r,e){var n,o;if(u){if(x){if(e)for(n in D)if(o=a[n],o&&p(o,t))try{delete o[t]}catch(i){}if(C[t]&&!e)return;try{return h(C,t,e?r:F&&C[t]||r)}catch(i){}}for(n in D)o=a[n],!o||o[t]&&!e||h(o,t,r)}};for(n in D)o=a[n],i=o&&o.prototype,i?O(i)[k]=o:F=!1;for(n in L)o=a[n],i=o&&o.prototype,i&&(O(i)[k]=o);if((!F||!c(C)||C===Function.prototype)&&(C=function(){throw new _("Incorrect invocation")},F))for(n in D)a[n]&&x(a[n],C);if((!F||!B||B===M)&&(B=C.prototype,F))for(n in D)a[n]&&x(a[n].prototype,B);if(F&&b(P)!==B&&x(P,B),u&&!p(B,I))for(n in R=!0,g(B,I,{configurable:!0,get:function(){return f(this)?this[U]:void 0}}),D)a[n]&&v(a[n],U,n);t.exports={NATIVE_ARRAY_BUFFER_VIEWS:F,TYPED_ARRAY_TAG:R&&U,aTypedArray:q,aTypedArrayConstructor:W,exportTypedArrayMethod:Y,exportTypedArrayStaticMethod:G,getTypedArrayConstructor:V,isView:z,isTypedArray:N,TypedArray:C,TypedArrayPrototype:B}},5370:(t,r,e)=>{"use strict";var n=e(6198);t.exports=function(t,r,e){var o=0,i=arguments.length>2?e:n(r),s=new t(i);while(i>o)s[o]=r[o++];return s}},9617:(t,r,e)=>{"use strict";var n=e(5397),o=e(5610),i=e(6198),s=function(t){return function(r,e,s){var u=n(r),a=i(u);if(0===a)return!t&&-1;var c,f=o(s,a);if(t&&e!==e){while(a>f)if(c=u[f++],c!==c)return!0}else for(;a>f;f++)if((t||f in u)&&u[f]===e)return t||f||0;return!t&&-1}};t.exports={includes:s(!0),indexOf:s(!1)}},4527:(t,r,e)=>{"use strict";var n=e(3724),o=e(4376),i=TypeError,s=Object.getOwnPropertyDescriptor,u=n&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(t){return t instanceof TypeError}}();t.exports=u?function(t,r){if(o(t)&&!s(t,"length").writable)throw new i("Cannot set read only .length");return t.length=r}:function(t,r){return t.length=r}},7628:(t,r,e)=>{"use strict";var n=e(6198);t.exports=function(t,r){for(var e=n(t),o=new r(e),i=0;i{"use strict";var n=e(6198),o=e(1291),i=RangeError;t.exports=function(t,r,e,s){var u=n(t),a=o(e),c=a<0?u+a:a;if(c>=u||c<0)throw new i("Incorrect index");for(var f=new r(u),p=0;p{"use strict";var n=e(9504),o=n({}.toString),i=n("".slice);t.exports=function(t){return i(o(t),8,-1)}},6955:(t,r,e)=>{"use strict";var n=e(2140),o=e(4901),i=e(4576),s=e(8227),u=s("toStringTag"),a=Object,c="Arguments"===i(function(){return arguments}()),f=function(t,r){try{return t[r]}catch(e){}};t.exports=n?i:function(t){var r,e,n;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(e=f(r=a(t),u))?e:c?i(r):"Object"===(n=i(r))&&o(r.callee)?"Arguments":n}},7740:(t,r,e)=>{"use strict";var n=e(9297),o=e(5031),i=e(7347),s=e(4913);t.exports=function(t,r,e){for(var u=o(r),a=s.f,c=i.f,f=0;f{"use strict";var n=e(9039);t.exports=!n((function(){function t(){}return t.prototype.constructor=null,Object.getPrototypeOf(new t)!==t.prototype}))},6699:(t,r,e)=>{"use strict";var n=e(3724),o=e(4913),i=e(6980);t.exports=n?function(t,r,e){return o.f(t,r,i(1,e))}:function(t,r,e){return t[r]=e,t}},6980:t=>{"use strict";t.exports=function(t,r){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:r}}},2106:(t,r,e)=>{"use strict";var n=e(283),o=e(4913);t.exports=function(t,r,e){return e.get&&n(e.get,r,{getter:!0}),e.set&&n(e.set,r,{setter:!0}),o.f(t,r,e)}},6840:(t,r,e)=>{"use strict";var n=e(4901),o=e(4913),i=e(283),s=e(9433);t.exports=function(t,r,e,u){u||(u={});var a=u.enumerable,c=void 0!==u.name?u.name:r;if(n(e)&&i(e,c,u),u.global)a?t[r]=e:s(r,e);else{try{u.unsafe?t[r]&&(a=!0):delete t[r]}catch(f){}a?t[r]=e:o.f(t,r,{value:e,enumerable:!1,configurable:!u.nonConfigurable,writable:!u.nonWritable})}return t}},9433:(t,r,e)=>{"use strict";var n=e(4475),o=Object.defineProperty;t.exports=function(t,r){try{o(n,t,{value:r,configurable:!0,writable:!0})}catch(e){n[t]=r}return r}},3724:(t,r,e)=>{"use strict";var n=e(9039);t.exports=!n((function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]}))},4483:(t,r,e)=>{"use strict";var n,o,i,s,u=e(4475),a=e(9714),c=e(1548),f=u.structuredClone,p=u.ArrayBuffer,y=u.MessageChannel,l=!1;if(c)l=function(t){f(t,{transfer:[t]})};else if(p)try{y||(n=a("worker_threads"),n&&(y=n.MessageChannel)),y&&(o=new y,i=new p(2),s=function(t){o.port1.postMessage(null,[t])},2===i.byteLength&&(s(i),0===i.byteLength&&(l=s)))}catch(v){}t.exports=l},4055:(t,r,e)=>{"use strict";var n=e(4475),o=e(34),i=n.document,s=o(i)&&o(i.createElement);t.exports=function(t){return s?i.createElement(t):{}}},6837:t=>{"use strict";var r=TypeError,e=9007199254740991;t.exports=function(t){if(t>e)throw r("Maximum allowed index exceeded");return t}},7290:(t,r,e)=>{"use strict";var n=e(516),o=e(9088);t.exports=!n&&!o&&"object"==typeof window&&"object"==typeof document},516:t=>{"use strict";t.exports="object"==typeof Deno&&Deno&&"object"==typeof Deno.version},9088:(t,r,e)=>{"use strict";var n=e(4475),o=e(4576);t.exports="process"===o(n.process)},9392:t=>{"use strict";t.exports="undefined"!=typeof navigator&&String(navigator.userAgent)||""},7388:(t,r,e)=>{"use strict";var n,o,i=e(4475),s=e(9392),u=i.process,a=i.Deno,c=u&&u.versions||a&&a.version,f=c&&c.v8;f&&(n=f.split("."),o=n[0]>0&&n[0]<4?1:+(n[0]+n[1])),!o&&s&&(n=s.match(/Edge\/(\d+)/),(!n||n[1]>=74)&&(n=s.match(/Chrome\/(\d+)/),n&&(o=+n[1]))),t.exports=o},8727:t=>{"use strict";t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},6518:(t,r,e)=>{"use strict";var n=e(4475),o=e(7347).f,i=e(6699),s=e(6840),u=e(9433),a=e(7740),c=e(2796);t.exports=function(t,r){var e,f,p,y,l,v,h=t.target,g=t.global,d=t.stat;if(f=g?n:d?n[h]||u(h,{}):n[h]&&n[h].prototype,f)for(p in r){if(l=r[p],t.dontCallGetSet?(v=o(f,p),y=v&&v.value):y=f[p],e=c(g?p:h+(d?".":"#")+p,t.forced),!e&&void 0!==y){if(typeof l==typeof y)continue;a(l,y)}(t.sham||y&&y.sham)&&i(l,"sham",!0),s(f,p,l,t)}}},9039:t=>{"use strict";t.exports=function(t){try{return!!t()}catch(r){return!0}}},616:(t,r,e)=>{"use strict";var n=e(9039);t.exports=!n((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")}))},9565:(t,r,e)=>{"use strict";var n=e(616),o=Function.prototype.call;t.exports=n?o.bind(o):function(){return o.apply(o,arguments)}},350:(t,r,e)=>{"use strict";var n=e(3724),o=e(9297),i=Function.prototype,s=n&&Object.getOwnPropertyDescriptor,u=o(i,"name"),a=u&&"something"===function(){}.name,c=u&&(!n||n&&s(i,"name").configurable);t.exports={EXISTS:u,PROPER:a,CONFIGURABLE:c}},6706:(t,r,e)=>{"use strict";var n=e(9504),o=e(9306);t.exports=function(t,r,e){try{return n(o(Object.getOwnPropertyDescriptor(t,r)[e]))}catch(i){}}},9504:(t,r,e)=>{"use strict";var n=e(616),o=Function.prototype,i=o.call,s=n&&o.bind.bind(i,i);t.exports=n?s:function(t){return function(){return i.apply(t,arguments)}}},7751:(t,r,e)=>{"use strict";var n=e(4475),o=e(4901),i=function(t){return o(t)?t:void 0};t.exports=function(t,r){return arguments.length<2?i(n[t]):n[t]&&n[t][r]}},5966:(t,r,e)=>{"use strict";var n=e(9306),o=e(4117);t.exports=function(t,r){var e=t[r];return o(e)?void 0:n(e)}},4475:function(t,r,e){"use strict";var n=function(t){return t&&t.Math===Math&&t};t.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof e.g&&e.g)||n("object"==typeof this&&this)||function(){return this}()||Function("return this")()},9297:(t,r,e)=>{"use strict";var n=e(9504),o=e(8981),i=n({}.hasOwnProperty);t.exports=Object.hasOwn||function(t,r){return i(o(t),r)}},421:t=>{"use strict";t.exports={}},5917:(t,r,e)=>{"use strict";var n=e(3724),o=e(9039),i=e(4055);t.exports=!n&&!o((function(){return 7!==Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},7055:(t,r,e)=>{"use strict";var n=e(9504),o=e(9039),i=e(4576),s=Object,u=n("".split);t.exports=o((function(){return!s("z").propertyIsEnumerable(0)}))?function(t){return"String"===i(t)?u(t,""):s(t)}:s},3706:(t,r,e)=>{"use strict";var n=e(9504),o=e(4901),i=e(7629),s=n(Function.toString);o(i.inspectSource)||(i.inspectSource=function(t){return s(t)}),t.exports=i.inspectSource},1181:(t,r,e)=>{"use strict";var n,o,i,s=e(8622),u=e(4475),a=e(34),c=e(6699),f=e(9297),p=e(7629),y=e(6119),l=e(421),v="Object already initialized",h=u.TypeError,g=u.WeakMap,d=function(t){return i(t)?o(t):n(t,{})},b=function(t){return function(r){var e;if(!a(r)||(e=o(r)).type!==t)throw new h("Incompatible receiver, "+t+" required");return e}};if(s||p.state){var x=p.state||(p.state=new g);x.get=x.get,x.has=x.has,x.set=x.set,n=function(t,r){if(x.has(t))throw new h(v);return r.facade=t,x.set(t,r),r},o=function(t){return x.get(t)||{}},i=function(t){return x.has(t)}}else{var w=y("state");l[w]=!0,n=function(t,r){if(f(t,w))throw new h(v);return r.facade=t,c(t,w,r),r},o=function(t){return f(t,w)?t[w]:{}},i=function(t){return f(t,w)}}t.exports={set:n,get:o,has:i,enforce:d,getterFor:b}},4376:(t,r,e)=>{"use strict";var n=e(4576);t.exports=Array.isArray||function(t){return"Array"===n(t)}},1108:(t,r,e)=>{"use strict";var n=e(6955);t.exports=function(t){var r=n(t);return"BigInt64Array"===r||"BigUint64Array"===r}},4901:t=>{"use strict";var r="object"==typeof document&&document.all;t.exports="undefined"==typeof r&&void 0!==r?function(t){return"function"==typeof t||t===r}:function(t){return"function"==typeof t}},2796:(t,r,e)=>{"use strict";var n=e(9039),o=e(4901),i=/#|\.prototype\./,s=function(t,r){var e=a[u(t)];return e===f||e!==c&&(o(r)?n(r):!!r)},u=s.normalize=function(t){return String(t).replace(i,".").toLowerCase()},a=s.data={},c=s.NATIVE="N",f=s.POLYFILL="P";t.exports=s},4117:t=>{"use strict";t.exports=function(t){return null===t||void 0===t}},34:(t,r,e)=>{"use strict";var n=e(4901);t.exports=function(t){return"object"==typeof t?null!==t:n(t)}},3925:(t,r,e)=>{"use strict";var n=e(34);t.exports=function(t){return n(t)||null===t}},6395:t=>{"use strict";t.exports=!1},757:(t,r,e)=>{"use strict";var n=e(7751),o=e(4901),i=e(1625),s=e(7040),u=Object;t.exports=s?function(t){return"symbol"==typeof t}:function(t){var r=n("Symbol");return o(r)&&i(r.prototype,u(t))}},6198:(t,r,e)=>{"use strict";var n=e(8014);t.exports=function(t){return n(t.length)}},283:(t,r,e)=>{"use strict";var n=e(9504),o=e(9039),i=e(4901),s=e(9297),u=e(3724),a=e(350).CONFIGURABLE,c=e(3706),f=e(1181),p=f.enforce,y=f.get,l=String,v=Object.defineProperty,h=n("".slice),g=n("".replace),d=n([].join),b=u&&!o((function(){return 8!==v((function(){}),"length",{value:8}).length})),x=String(String).split("String"),w=t.exports=function(t,r,e){"Symbol("===h(l(r),0,7)&&(r="["+g(l(r),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),e&&e.getter&&(r="get "+r),e&&e.setter&&(r="set "+r),(!s(t,"name")||a&&t.name!==r)&&(u?v(t,"name",{value:r,configurable:!0}):t.name=r),b&&e&&s(e,"arity")&&t.length!==e.arity&&v(t,"length",{value:e.arity});try{e&&s(e,"constructor")&&e.constructor?u&&v(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(o){}var n=p(t);return s(n,"source")||(n.source=d(x,"string"==typeof r?r:"")),t};Function.prototype.toString=w((function(){return i(this)&&y(this).source||c(this)}),"toString")},741:t=>{"use strict";var r=Math.ceil,e=Math.floor;t.exports=Math.trunc||function(t){var n=+t;return(n>0?e:r)(n)}},4913:(t,r,e)=>{"use strict";var n=e(3724),o=e(5917),i=e(8686),s=e(8551),u=e(6969),a=TypeError,c=Object.defineProperty,f=Object.getOwnPropertyDescriptor,p="enumerable",y="configurable",l="writable";r.f=n?i?function(t,r,e){if(s(t),r=u(r),s(e),"function"===typeof t&&"prototype"===r&&"value"in e&&l in e&&!e[l]){var n=f(t,r);n&&n[l]&&(t[r]=e.value,e={configurable:y in e?e[y]:n[y],enumerable:p in e?e[p]:n[p],writable:!1})}return c(t,r,e)}:c:function(t,r,e){if(s(t),r=u(r),s(e),o)try{return c(t,r,e)}catch(n){}if("get"in e||"set"in e)throw new a("Accessors not supported");return"value"in e&&(t[r]=e.value),t}},7347:(t,r,e)=>{"use strict";var n=e(3724),o=e(9565),i=e(8773),s=e(6980),u=e(5397),a=e(6969),c=e(9297),f=e(5917),p=Object.getOwnPropertyDescriptor;r.f=n?p:function(t,r){if(t=u(t),r=a(r),f)try{return p(t,r)}catch(e){}if(c(t,r))return s(!o(i.f,t,r),t[r])}},8480:(t,r,e)=>{"use strict";var n=e(1828),o=e(8727),i=o.concat("length","prototype");r.f=Object.getOwnPropertyNames||function(t){return n(t,i)}},3717:(t,r)=>{"use strict";r.f=Object.getOwnPropertySymbols},2787:(t,r,e)=>{"use strict";var n=e(9297),o=e(4901),i=e(8981),s=e(6119),u=e(2211),a=s("IE_PROTO"),c=Object,f=c.prototype;t.exports=u?c.getPrototypeOf:function(t){var r=i(t);if(n(r,a))return r[a];var e=r.constructor;return o(e)&&r instanceof e?e.prototype:r instanceof c?f:null}},1625:(t,r,e)=>{"use strict";var n=e(9504);t.exports=n({}.isPrototypeOf)},1828:(t,r,e)=>{"use strict";var n=e(9504),o=e(9297),i=e(5397),s=e(9617).indexOf,u=e(421),a=n([].push);t.exports=function(t,r){var e,n=i(t),c=0,f=[];for(e in n)!o(u,e)&&o(n,e)&&a(f,e);while(r.length>c)o(n,e=r[c++])&&(~s(f,e)||a(f,e));return f}},8773:(t,r)=>{"use strict";var e={}.propertyIsEnumerable,n=Object.getOwnPropertyDescriptor,o=n&&!e.call({1:2},1);r.f=o?function(t){var r=n(this,t);return!!r&&r.enumerable}:e},2967:(t,r,e)=>{"use strict";var n=e(6706),o=e(34),i=e(7750),s=e(3506);t.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var t,r=!1,e={};try{t=n(Object.prototype,"__proto__","set"),t(e,[]),r=e instanceof Array}catch(u){}return function(e,n){return i(e),s(n),o(e)?(r?t(e,n):e.__proto__=n,e):e}}():void 0)},4270:(t,r,e)=>{"use strict";var n=e(9565),o=e(4901),i=e(34),s=TypeError;t.exports=function(t,r){var e,u;if("string"===r&&o(e=t.toString)&&!i(u=n(e,t)))return u;if(o(e=t.valueOf)&&!i(u=n(e,t)))return u;if("string"!==r&&o(e=t.toString)&&!i(u=n(e,t)))return u;throw new s("Can't convert object to primitive value")}},5031:(t,r,e)=>{"use strict";var n=e(7751),o=e(9504),i=e(8480),s=e(3717),u=e(8551),a=o([].concat);t.exports=n("Reflect","ownKeys")||function(t){var r=i.f(u(t)),e=s.f;return e?a(r,e(t)):r}},7750:(t,r,e)=>{"use strict";var n=e(4117),o=TypeError;t.exports=function(t){if(n(t))throw new o("Can't call method on "+t);return t}},6119:(t,r,e)=>{"use strict";var n=e(5745),o=e(3392),i=n("keys");t.exports=function(t){return i[t]||(i[t]=o(t))}},7629:(t,r,e)=>{"use strict";var n=e(6395),o=e(4475),i=e(9433),s="__core-js_shared__",u=t.exports=o[s]||i(s,{});(u.versions||(u.versions=[])).push({version:"3.37.1",mode:n?"pure":"global",copyright:"© 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.37.1/LICENSE",source:"https://github.com/zloirock/core-js"})},5745:(t,r,e)=>{"use strict";var n=e(7629);t.exports=function(t,r){return n[t]||(n[t]=r||{})}},1548:(t,r,e)=>{"use strict";var n=e(4475),o=e(9039),i=e(7388),s=e(7290),u=e(516),a=e(9088),c=n.structuredClone;t.exports=!!c&&!o((function(){if(u&&i>92||a&&i>94||s&&i>97)return!1;var t=new ArrayBuffer(8),r=c(t,{transfer:[t]});return 0!==t.byteLength||8!==r.byteLength}))},4495:(t,r,e)=>{"use strict";var n=e(7388),o=e(9039),i=e(4475),s=i.String;t.exports=!!Object.getOwnPropertySymbols&&!o((function(){var t=Symbol("symbol detection");return!s(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&n&&n<41}))},5610:(t,r,e)=>{"use strict";var n=e(1291),o=Math.max,i=Math.min;t.exports=function(t,r){var e=n(t);return e<0?o(e+r,0):i(e,r)}},5854:(t,r,e)=>{"use strict";var n=e(2777),o=TypeError;t.exports=function(t){var r=n(t,"number");if("number"==typeof r)throw new o("Can't convert number to bigint");return BigInt(r)}},7696:(t,r,e)=>{"use strict";var n=e(1291),o=e(8014),i=RangeError;t.exports=function(t){if(void 0===t)return 0;var r=n(t),e=o(r);if(r!==e)throw new i("Wrong length or index");return e}},5397:(t,r,e)=>{"use strict";var n=e(7055),o=e(7750);t.exports=function(t){return n(o(t))}},1291:(t,r,e)=>{"use strict";var n=e(741);t.exports=function(t){var r=+t;return r!==r||0===r?0:n(r)}},8014:(t,r,e)=>{"use strict";var n=e(1291),o=Math.min;t.exports=function(t){var r=n(t);return r>0?o(r,9007199254740991):0}},8981:(t,r,e)=>{"use strict";var n=e(7750),o=Object;t.exports=function(t){return o(n(t))}},2777:(t,r,e)=>{"use strict";var n=e(9565),o=e(34),i=e(757),s=e(5966),u=e(4270),a=e(8227),c=TypeError,f=a("toPrimitive");t.exports=function(t,r){if(!o(t)||i(t))return t;var e,a=s(t,f);if(a){if(void 0===r&&(r="default"),e=n(a,t,r),!o(e)||i(e))return e;throw new c("Can't convert object to primitive value")}return void 0===r&&(r="number"),u(t,r)}},6969:(t,r,e)=>{"use strict";var n=e(2777),o=e(757);t.exports=function(t){var r=n(t,"string");return o(r)?r:r+""}},2140:(t,r,e)=>{"use strict";var n=e(8227),o=n("toStringTag"),i={};i[o]="z",t.exports="[object z]"===String(i)},9714:(t,r,e)=>{"use strict";var n=e(9088);t.exports=function(t){try{if(n)return Function('return require("'+t+'")')()}catch(r){}}},6823:t=>{"use strict";var r=String;t.exports=function(t){try{return r(t)}catch(e){return"Object"}}},3392:(t,r,e)=>{"use strict";var n=e(9504),o=0,i=Math.random(),s=n(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+s(++o+i,36)}},7040:(t,r,e)=>{"use strict";var n=e(4495);t.exports=n&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},8686:(t,r,e)=>{"use strict";var n=e(3724),o=e(9039);t.exports=n&&o((function(){return 42!==Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))},8622:(t,r,e)=>{"use strict";var n=e(4475),o=e(4901),i=n.WeakMap;t.exports=o(i)&&/native code/.test(String(i))},8227:(t,r,e)=>{"use strict";var n=e(4475),o=e(5745),i=e(9297),s=e(3392),u=e(4495),a=e(7040),c=n.Symbol,f=o("wks"),p=a?c["for"]||c:c&&c.withoutSetter||s;t.exports=function(t){return i(f,t)||(f[t]=u&&i(c,t)?c[t]:p("Symbol."+t)),f[t]}},6573:(t,r,e)=>{"use strict";var n=e(3724),o=e(2106),i=e(3238),s=ArrayBuffer.prototype;n&&!("detached"in s)&&o(s,"detached",{configurable:!0,get:function(){return i(this)}})},7936:(t,r,e)=>{"use strict";var n=e(6518),o=e(5636);o&&n({target:"ArrayBuffer",proto:!0},{transferToFixedLength:function(){return o(this,arguments.length?arguments[0]:void 0,!1)}})},8100:(t,r,e)=>{"use strict";var n=e(6518),o=e(5636);o&&n({target:"ArrayBuffer",proto:!0},{transfer:function(){return o(this,arguments.length?arguments[0]:void 0,!0)}})},4114:(t,r,e)=>{"use strict";var n=e(6518),o=e(8981),i=e(6198),s=e(4527),u=e(6837),a=e(9039),c=a((function(){return 4294967297!==[].push.call({length:4294967296},1)})),f=function(){try{Object.defineProperty([],"length",{writable:!1}).push()}catch(t){return t instanceof TypeError}},p=c||!f();n({target:"Array",proto:!0,arity:1,forced:p},{push:function(t){var r=o(this),e=i(r),n=arguments.length;u(e+n);for(var a=0;a{"use strict";var n=e(7628),o=e(4644),i=o.aTypedArray,s=o.exportTypedArrayMethod,u=o.getTypedArrayConstructor;s("toReversed",(function(){return n(i(this),u(this))}))},4732:(t,r,e)=>{"use strict";var n=e(4644),o=e(9504),i=e(9306),s=e(5370),u=n.aTypedArray,a=n.getTypedArrayConstructor,c=n.exportTypedArrayMethod,f=o(n.TypedArrayPrototype.sort);c("toSorted",(function(t){void 0!==t&&i(t);var r=u(this),e=s(a(r),r);return f(e,t)}))},9577:(t,r,e)=>{"use strict";var n=e(9928),o=e(4644),i=e(1108),s=e(1291),u=e(5854),a=o.aTypedArray,c=o.getTypedArrayConstructor,f=o.exportTypedArrayMethod,p=!!function(){try{new Int8Array(1)["with"](2,{valueOf:function(){throw 8}})}catch(t){return 8===t}}();f("with",{with:function(t,r){var e=a(this),o=s(t),f=i(e)?u(r):+r;return n(e,c(e),o,f)}}["with"],!p)}},r={};function e(n){var o=r[n];if(void 0!==o)return o.exports;var i=r[n]={exports:{}};return t[n].call(i.exports,i,i.exports,e),i.exports}(()=>{e.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"===typeof window)return window}}()})();e(4114),e(6573),e(8100),e(7936),e(7467),e(4732),e(9577);const n=16,o=n/8,i=16e3,s=1;let u=0,a=[];const c={sampleRate:44e3,numChannels:1,useDownsample:!0,useTrim:!0,quietTrimThreshold:8e-4,quietTrimSlackBack:4e3};function f(t){Object.assign(c,t),h()}function p(t){for(let r=0;rc.quietTrimThreshold&&(0===a&&(a=s),f=s),i[s]=o/p,s++,u=r}return c.useTrim?i.slice(Math.max(0,a-c.quietTrimSlackBack),Math.min(o,f+c.quietTrimSlackBack)):i}self.onmessage=t=>{switch(t.data.command){case"init":f(t.data.config);break;case"record":p(t.data.buffer);break;case"exportWav":y(t.data.type);break;case"getBuffer":l();break;case"clear":v();break;case"close":self.close();break;default:break}}})(); \ No newline at end of file diff --git a/lex-web-ui/package-lock.json b/lex-web-ui/package-lock.json index c882dac9d..54829723f 100644 --- a/lex-web-ui/package-lock.json +++ b/lex-web-ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "lex-web-ui", - "version": "0.21.4", + "version": "0.21.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "lex-web-ui", - "version": "0.21.4", + "version": "0.21.5", "license": "Amazon Software License", "dependencies": { "amazon-connect-chatjs": "^2.3.0", diff --git a/lex-web-ui/package.json b/lex-web-ui/package.json index b817d5a27..6530538df 100644 --- a/lex-web-ui/package.json +++ b/lex-web-ui/package.json @@ -1,6 +1,6 @@ { "name": "lex-web-ui", - "version": "0.21.4", + "version": "0.21.5", "description": "Amazon Lex Web Interface", "author": "AWS", "license": "Amazon Software License", diff --git a/package-lock.json b/package-lock.json index 40fffad55..48287c45a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "aws-lex-web-ui", - "version": "0.21.4", + "version": "0.21.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "aws-lex-web-ui", - "version": "0.21.4", + "version": "0.21.5", "license": "SEE LICENSE IN LICENSE", "dependencies": { "amazon-cognito-auth-js": "^1.2.4", diff --git a/package.json b/package.json index 5408527d6..d7701ac49 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aws-lex-web-ui", - "version": "0.21.4", + "version": "0.21.5", "description": "Sample Amazon Lex Web Interface", "main": "dist/lex-web-ui.min.js", "repository": { diff --git a/templates/README.md b/templates/README.md index b2264eda4..59fef9cf0 100644 --- a/templates/README.md +++ b/templates/README.md @@ -14,24 +14,14 @@ hosted in an AWS owned S3 bucket (see below for instructions on hosting your own). Once deployed, the CloudFormation stack outputs links to resources including the sample site and iframe embedding instructions. -### Deployment Modes -There are two master CloudFormation templates used for two different -deployment modes: - -1. [CodeBuild Mode](#codebuild-deployment-mode) configures and deploys +### Deployment Mode +[CodeBuild Mode](#codebuild-deployment-mode) configures and deploys directly to S3 from a CodeBuild project. It is deployed using he [master.yaml](master.yaml) template. This mode uses the pre-built version of the chatbot UI library in the `dist` directory at the root of this repository. By using the pre-built library, this makes this mode faster and simpler to manage -2. [Pipeline Mode](#pipeline-deployment-mode) configures, -builds and deploys using a CI/CD pipeline (CodeCommit, -CodeBuild and CodePipeline). It is deployed using the -[master-pipeline.yaml](master-pipeline.yaml) template. This mode -creates an automated deployment pipeline that performs a full build of -the application from source. This mode provides finer customization and -the ability to automatically push your own changes by committing to your -code repository + ### Regions The lex-web-ui can be launched into regions other than us-east-1 where Lex, Polly, Cognito, Codebuild are supported. @@ -64,14 +54,10 @@ launch your bucket in the target region using the master.yaml, make sure to chan "[your-lex-bootstrap-bucket-name]" and change the Bootstrap Prefix to be just "artifacts". ### Launch -To launch a stack using the CodeBuild Mode (faster and easier), click this button: +To launch a stack click this button: [![cloudformation-launch-stack](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=lex-web-ui&templateURL=https://s3.amazonaws.com/aws-bigdata-blog/artifacts/aws-lex-web-ui/artifacts/templates/master.yaml) -Click the following button to launch a stack using the Pipeline Mode: - -[![cloudformation-launch-stack](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=lex-web-ui&templateURL=https://s3.amazonaws.com/aws-bigdata-blog/artifacts/aws-lex-web-ui/artifacts/templates/master-pipeline.yaml) - ### CloudFormation Resources The CloudFormation stack can create resources in your AWS account including: @@ -83,9 +69,7 @@ used to pass temporary AWS credentials to the web app. You can optionally pass the ID of an existing Cognito Identity Pool to avoid creating a new one. - [CodeBuild](https://aws.amazon.com/codebuild/) project to configure -and deploy to S3 when using the CodeBuild Deployment Mode. If using the -Pipeline Deployment Mode, a CodeBuild project is created to bootstrap -a CodeCommit repository whit the application source. +and deploy to S3 when using the CodeBuild Deployment Mode. - [S3](https://aws.amazon.com/s3/) buckets to host the web application and to store build artifacts. - [Lambda](https://aws.amazon.com/lambda/) functions used as CloudFormation @@ -96,16 +80,6 @@ groups automatically created to log the output of the Lambda functions - Associated [IAM roles](http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) for the stack resources -If using the Pipeline Deployment Mode, the stack also creates the -following resources: -- [CodeCommit](https://aws.amazon.com/codecommit/) -repository loaded with the source code in this project. This is only -created when using the pipeline deployment mode -- A continuous delivery pipeline using [CodePipeline](https://aws.amazon.com/codepipeline/) -and [CodeBuild](https://aws.amazon.com/codebuild/). -The pipeline automatically builds and deploys changes to the app committed - to the CodeCommit repo - ### CloudFormation Templates The following table lists the CloudFormation templates used to create the stacks: @@ -113,13 +87,10 @@ the stacks: | Template | Description | | --- | --- | | [master.yaml](./master.yaml) | This is the master template used to deploy the stack using the CodeBuild Mode | -| [master-pipeline.yaml](./master-pipeline.yaml) | This is the master template used to deploy the stack using the Pipeline Mode | | [lexbot.yaml](./lexbot.yaml) | Lex bot and associated resources (i.e. intents and slot types). | | [cognito.yaml](./cognito.yaml) | Cognito Identity Pool and IAM role for unauthenticated identity access. | | [cognitouserpoolconfig.yaml](./cognitouserpoolconfig.yaml) | This template updates the cognito user pool with application client and domain configuration to enable login through either Cognito or other Identity Providers linked via federation. | | [codebuild-deploy.yaml](./codebuild-deploy.yaml) | Uses CodeBuild to create a configuration and deploy it along the site to S3. Used in CodeBuild Mode | -| [coderepo.yaml](./coderepo.yaml) | CodeCommit repo dynamically initialized with the files in this repo using CodeBuild and a custom resource. Used in Pipeline Mode | -| [pipeline.yaml](./pipeline.yaml) | Continuous deployment pipeline of the Lex Web UI Application using CodePipeline and CodeBuild. The pipeline takes the source from CodeCommit, builds the Lex web UI application using CodeBuild and deploys the app to an S3 bucket. Used in Pipeline Mode | ### Parameters When launching the stack, you will see a list of available parameters @@ -187,15 +158,6 @@ all nested stacks will be in the `CREATE_COMPLETE` green status. At this point, the master stack will reference the resources in the output section. -**NOTE**: When deploying with the [Pipeline -Mode](#pipeline-deployment-mode), the web app links will be available -once the pipeline has completed deploying (this process can take a -while). See the `PipelineUrl` output link to monitor the deployment -process. Similarly, in [CodeBuild Mode](#codebuild-deployment-mode) -there may be a small delay before the links are available. In this mode, -you can monitor the build progress by browsing to the `CodeBuildUrl` -output variable. - Here is a list of the most relevant output variables: - `WebAppUrl`: URL of the web app running on a full page - `ParentPageUrl`: URL of the web app running in an iframe. This is an @@ -213,19 +175,10 @@ pool ID was passed as a parameter to the stack during creation. optional output that is returned only when the stack creates the sample Lex bot. It is not returned if an existing Bot was passed as a parameter to the stack during creation - -This output variable is specific to the CodeBuild Mode: - `CodeBuildUrl`: Link to CodeBuild project in the AWS console. After the stack is successfully launched, the build is automatically started. You can click on this link to monitor the build progress -These output variables are specific to the Pipeline Mode: -- `PipelineUrl`: Link to CodePipeline in the AWS console. After the stack -is successfully launched, the pipeline automatically starts the build and -deployment process. You can click on this link to monitor the pipeline -- `CodeCommitRepoUrl`: When using the Pipeline Deployment Mode, this is -the CodeCommit repository URL. You can clone the repo using this link -and push changes to it to have the pipeline build and deploy the web app ## Build and Deployment Overview The CloudFormation stack builds and deploys the application using @@ -263,60 +216,6 @@ file contains the source in this project and it is regularly updated. If you want to use your own source, see the [Deploy Using My Own Bootstrap S3 Bucket](#deploy-using-my-own-bootstrap-s3-bucket) section below. -## Pipeline Deployment Mode -When creating the stack with the -[master-pipeline.yaml](master-pipeline.yaml) template, the stack creates -a deployment pipeline using -[CodeCommit](https://aws.amazon.com/codecommit/) -[CodePipeline](https://aws.amazon.com/codepipeline/) -and [CodeBuild](https://aws.amazon.com/codebuild/) -which automatically builds and deploys changes to the app committed -to the CodeCommit repo. - -### Diagram -Here is a diagram of the CloudFormation stack created by the pipeline deployment mode: - - - -### Launching Using the Pipeline -To deploy a CloudFormation stack with a working demo of the application, -follow the steps below: - -1. Click the following CloudFormation button to launch your own copy of -the sample application stack in the us-east-1 (N. Virginia) AWS region: -[![cloudformation-launch-stack](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=lex-web-ui&templateURL=https://s3.amazonaws.com/aws-bigdata-blog/artifacts/aws-lex-web-ui/artifacts/templates/master-pipeline.yaml) -2. You can accept the defaults in the CloudFormation Create Stack Wizard -up until the last step. At the last step, when prompted to create -the stack, select the checkmark that says: "I acknowledge that AWS -CloudFormation might create IAM resources with custom names". It takes -about 10 minutes for the CloudFormation stacks to got to `CREATE_COMPLETE` -status -3. Once the status of all the CloudFormation stacks -is `CREATE_COMPLETE`, click on the `PipelineUrl` link in the output -section of the master stack. This will take you to the CodePipeline -console. You can monitor the progress of the deployment pipeline from -there. It takes about 10 minutes to build and deploy the application -4. Once the pipeline has deployed successfully, go back to the -output section of the master CloudFormation stack and click on the -`ParentPageUrl` link. You can also browse to the `WebAppUrl` link. Those -links will take you to the sample application running as an embedded -iframe or as a stand-alone web application respectively - -### Deployment Pipeline -The source of this project is automatically forked into a CodeCommit -repository created by the CloudFormation stack. Any changes pushed to -the master branch of this forked repo will automatically kick off the -pipeline which runs a CodeBuild job to build and deploy a new version -of the web app. You will need to -[setup](http://docs.aws.amazon.com/codecommit/latest/userguide/setting-up.html) -CodeCommit to push changes to this repo. You can obtain the CodeCommit -git clone URL from the `CodeCommitRepoUrl` output variable of the -master stack. - -Here is a diagram of the deployment pipeline: - - - ## Directory Structure The following files and directories are relevant to the CloudFormation setup: @@ -393,9 +292,7 @@ parameter to `false` in the master stack. By default, the CloudFormation stacks use pre-staged files from an AWS owned S3 bucket. These files are dynamically downloaded by the CodeBuild project created by the CloudFormation stack and copied to S3 -buckets created in your account. Additionally, these files are used to -bootstrap the CodeCommit repo used as the CodePipeline source when using -the [Pipeline Deployment Mode](#pipeline-deployment-mode). +buckets created in your account. The bootstrap bucket name and prefix are controlled by the `BootstrapBucket` and `BootstrapPrefix` parameters of the master @@ -419,6 +316,6 @@ the [build](../build) directory under the root of the repo. This directory contains a `Makefile` that can be used to build the artifacts and upload the files to your S3 bucket. It uses the [aws cli](https://aws.amazon.com/cli/) to copy the files to S3 -4. Deploy the stack by using the `master.yml` or `master-pipeline` -templates. Change the the `BootstrapBucket` and `BootstrapPrefix` +4. Deploy the stack by using the `master.yml` template. +Change the the `BootstrapBucket` and `BootstrapPrefix` parameters to point to your own bucket and path diff --git a/templates/codebuild-deploy.yaml b/templates/codebuild-deploy.yaml index 873dc3bb0..fd2bc44b9 100644 --- a/templates/codebuild-deploy.yaml +++ b/templates/codebuild-deploy.yaml @@ -450,7 +450,7 @@ Parameters: Type: Number Description: > This is a required parameter. It defines a timestamp allow the codebuild to execute as long as the - timestamp from master.yaml and master-pipeline.yaml varies. + timestamp from master.yaml varies. ResourcePrefix: Type: String diff --git a/templates/coderepo.yaml b/templates/coderepo.yaml deleted file mode 100644 index b92dfcaea..000000000 --- a/templates/coderepo.yaml +++ /dev/null @@ -1,312 +0,0 @@ -AWSTemplateFormatVersion: 2010-09-09 -Description: > - This template creates a CodeCommit repo and initializes it with this - project sources. It uses CodeBuild and a custom resource to git push - the files into the repo. - -Parameters: - CodeCommitRepoName: - Type: String - Description: Name of CodeCommit repository name to be created. - Default: lex-web-ui - MinLength: 1 - MaxLength: 100 - AllowedPattern: '^[\w\.-]+$' - ConstraintDescription: Alphanumeric, dot and dash. - - CodeBuildName: - Type: String - Description: CodeBuild project used to initialize the code repo - Default: lex-web-ui-init - MinLength: 2 - MaxLength: 255 - AllowedPattern: '^[A-Za-z0-9][A-Za-z0-9\-_]{1,254}$' - ConstraintDescription: > - Should start with Alphanumeric. May contain alphanumeric, undescore - and dash. - - SourceBucket: - Description: S3 bucket where the source is located - Type: String - Default: aws-bigdata-blog - - SourceObject: - Description: S3 object zip file containing the project source - Type: String - Default: artifacts/aws-lex-web-ui/artifacts/src.zip - - CustomResourceCodeObject: - Type: String - Description: > - S3 object zip file containing Lambda custom resource functions - Default: artifacts/aws-lex-web-ui/artifacts/custom-resources.zip - - CognitoIdentityPoolId: - Type: String - Description: > - Cognito Identity Pool Id to used in the web app configuration. - MinLength: 1 - MaxLength: 55 - AllowedPattern: '^[\w-]+:[0-9a-f-]+$' - ConstraintDescription: > - Alphanumeric followed by a colum and ending with a hex uuid type. - - BotName: - Description: > - Name of Lex bot to be used in the web app configuration. - Type: String - Default: '' - MinLength: 0 - MaxLength: 50 - AllowedPattern: '(^$|^[a-zA-Z]+((_[a-zA-Z]+)*|([a-zA-Z]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex Bot name pattern. - - BotAlias: - Description: > - WARNING: For production deployments, use your bot's published alias here. - The $LATEST alias should only be used for manual testing. Amazon Lex limits - the number of runtime requests that you can make to the $LATEST version of - the bot. - Type: String - Default: '$LATEST' - MinLength: 2 - MaxLength: 50 - AllowedPattern: '(^$|^[$a-zA-Z]+((_[$a-zA-Z]+)*|([$a-zA-Z]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex Alias name pattern. - - LexV2BotId: - Description: > - Bot ID (not bot name) of an existing Lex V2 Bot to be used by the web ui. NOTE: You must - also enter your Bot alias ID in the LexV2BotAliasId field below. - Type: String - Default: '' - MaxLength: 50 - AllowedPattern: '(^$|^[a-zA-Z0-9]+((_[a-zA-Z0-9]+)*|([a-zA-Z0-9]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex V2 Bot name pattern. - - LexV2BotAliasId: - Description: > - Use your Lex V2 bot's alias id (not alias name) here. - Type: String - Default: '' - MinLength: 0 - MaxLength: 50 - AllowedPattern: '(^$|^[$a-zA-Z0-9]+((_[$a-zA-Z0-9]+)*|([$a-zA-Z0-9]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex V2 Alias name pattern. - - LexV2BotLocaleId: - Description: > - Use your bot's locale id here. By default this is en_US. Other Lex V2 supported values are - en_AU, en_GB, es_419, es_ES, es_US, fr_CA, fr_FR, it_IT. - See "https://docs.aws.amazon.com/lexv2/latest/dg/lex2.0.pdf" - for details on supported languages and locales. - Type: String - Default: 'en_US' - MinLength: 2 - MaxLength: 50 - -Resources: - CodeCommitRepo: - Type: AWS::CodeCommit::Repository - Properties: - RepositoryDescription: Lex Web UI - RepositoryName: !Ref CodeCommitRepoName - - CodeBuild: - Type: AWS::CodeBuild::Project - Properties: - Name: !Ref CodeBuildName - Description: Used to initialize the Lex Web UI CodeCommit Repo - Artifacts: - Type: NO_ARTIFACTS - Environment: - Type: LINUX_CONTAINER - Image: aws/codebuild/amazonlinux2-x86_64-standard:5.0 - ComputeType: BUILD_GENERAL1_SMALL - EnvironmentVariables: - - Name: REPO_URL - Value: !GetAtt CodeCommitRepo.CloneUrlHttp - - Name: POOL_ID - Value: !Ref CognitoIdentityPoolId - - Name: V2_BOT_ID - Value: !Ref LexV2BotId - - Name: V2_BOT_ALIAS_ID - Value: !Ref LexV2BotAliasId - - Name: V2_BOT_LOCALE_ID - Value: !Ref LexV2BotLocaleId - - Name: BOT_NAME - Value: !Ref BotName - - Name: BOT_ALIAS - Value: !Ref BotAlias - ServiceRole: !GetAtt CodeBuildRole.Arn - TimeoutInMinutes: 10 - Source: - Type: S3 - Location: !Sub "${SourceBucket}/${SourceObject}" - BuildSpec: !Sub | - version: 0.1 - phases: - install: - commands: - - n stable - - npm update -g npm - - make install-deps - pre_build: - commands: - - make config - build: - commands: - - aws configure set region "${AWS::Region}" - - git config --global user.name 'CodeCommit Init' - - git config --global user.email '<>' - - git config --global push.default simple - - git config --global "credential.https://git-codecommit.${AWS::Region}.amazonaws.com.helper" '!aws codecommit credential-helper $@' - - git config --global "credential.https://git-codecommit.${AWS::Region}.amazonaws.com.UseHttpPath" 'true' - - git init - - git add . - - git commit -a -m initial - - git remote add origin "${!REPO_URL}" - - git push --set-upstream origin master - - # custom resource to start code build project - CodeBuildStarter: - Type: Custom::CodeBuildStarter - Properties: - ServiceToken: !GetAtt CodeBuildStarterLambda.Arn - ProjectName: !Ref CodeBuild - - # Lambda function for custom resource - CodeBuildStarterLambda: - Type: AWS::Lambda::Function - Properties: - Code: - S3Bucket: !Ref SourceBucket - S3Key: !Ref CustomResourceCodeObject - Handler: codebuild-start.handler - Role: !GetAtt CodeBuildStarterLambdaRole.Arn - Runtime: python3.10 - Timeout: 120 - TracingConfig: - Mode: Active - - CodeBuildRole: - Type: AWS::IAM::Role - Properties: - Path: / - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Principal: - Service: - - codebuild.amazonaws.com - Effect: Allow - Action: - - sts:AssumeRole - Policies: - - PolicyName: CodeCommitGetListPush - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - codecommit:BatchGetRepositories - - codecommit:CreateBranch - - codecommit:Get* - - codecommit:GitPull - - codecommit:GitPush - - codecommit:List* - - codecommit:UpdateDefaultBranch - Resource: - - !GetAtt CodeCommitRepo.Arn - - PolicyName: S3GetObject - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - s3:GetObject* - Resource: - - !Sub "arn:aws:s3:::${SourceBucket}/${SourceObject}" - - PolicyName: CloudWatchLogsCodeBuild - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - logs:CreateLogGroup - - logs:CreateLogStream - - logs:PutLogEvents - Resource: - - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildName}" - - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildName}:*" - - CodeBuildStarterLambdaRole: - Type: AWS::IAM::Role - Properties: - Path: / - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Principal: - Service: - - lambda.amazonaws.com - Effect: Allow - Action: - - sts:AssumeRole - Policies: - - PolicyName: LogsForLambda - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - logs:CreateLogGroup - - logs:CreateLogStream - - logs:PutLogEvents - Resource: - - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*" - - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*:*" - - PolicyName: CodeBuildStart - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - codebuild:StartBuild - Resource: !GetAtt CodeBuild.Arn - - PolicyName: XRay - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - xray:PutTraceSegments - - xray:PutTelemetryRecords - Resource: "*" - - PolicyName: AllowVPCSupport - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - ec2:DescribeNetworkInterfaces - - ec2:CreateNetworkInterface - - ec2:DeleteNetworkInterface - Resource: "*" - -Outputs: - CodeCommitRepoUrl: - Description: CodeCommit repository clone URL - Value: !GetAtt CodeCommitRepo.CloneUrlHttp - - CodeCommitRepoArn: - Description: CodeCommit repository clone URL - Value: !GetAtt CodeCommitRepo.Arn - - CodeCommitRepoName: - Description: CodeCommit repository name - Value: !GetAtt CodeCommitRepo.Name diff --git a/templates/custom-resources/cfnresponse.py b/templates/custom-resources/cfnresponse.py new file mode 100644 index 000000000..e0b8f5b4d --- /dev/null +++ b/templates/custom-resources/cfnresponse.py @@ -0,0 +1,51 @@ +# Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Amazon Software License (the "License"). You may not use this file +# except in compliance with the License. A copy of the License is located at +# +# http://aws.amazon.com/asl/ +# +# or in the "license" file accompanying this file. This file is distributed on an "AS IS" +# BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the +# License for the specific language governing permissions and limitations under the License. + +import requests +import json + +SUCCESS = "SUCCESS" +FAILED = "FAILED" + +def send(event, context, responseStatus, responseData, physicalResourceId, reason): + responseUrl = event['ResponseURL'] + + print(responseUrl) + + responseBody = {} + responseBody['Status'] = responseStatus + responseBody['Reason'] = ('Reason: ' + json_dump_format(reason) + + '. See the details in CloudWatch Log Stream: ' + context.log_stream_name) + responseBody['PhysicalResourceId'] = physicalResourceId or context.log_stream_name + responseBody['StackId'] = event['StackId'] + responseBody['RequestId'] = event['RequestId'] + responseBody['LogicalResourceId'] = event['LogicalResourceId'] + responseBody['Data'] = responseData + + json_responseBody = json_dump_format(responseBody) + + print("Response body:\n" + json_responseBody) + + headers = { + 'content-type' : '', + 'content-length' : str(len(json_responseBody)) + } + + try: + response = requests.put(responseUrl, + data=json_responseBody, + headers=headers) + print ("Status code: " + response.reason) + except Exception as e: + print ("send(..) failed executing requests.put(..): " + str(e)) + +def json_dump_format(obj): + return json.dumps(obj, indent=4, sort_keys=True, default=str) diff --git a/templates/custom-resources/codebuild-start.py b/templates/custom-resources/codebuild-start.py new file mode 100644 index 000000000..13d8b3bec --- /dev/null +++ b/templates/custom-resources/codebuild-start.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python + +########################################################################## +# Copyright 2017-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Amazon Software License (the "License"). You may not use this file +# except in compliance with the License. A copy of the License is located at +# +# http://aws.amazon.com/asl/ +# +# or in the "license" file accompanying this file. This file is distributed on an "AS IS" +# BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the +# License for the specific language governing permissions and limitations under the License. +########################################################################## +""" CodeBuild Starter + +CloudFormation Custom Resource Lambda Function +""" + +import logging +import boto3 +import cfnresponse + + +codebuild_client = boto3.client('codebuild') + +DEFAULT_LOGGING_LEVEL = logging.INFO +logging.basicConfig(format='[%(levelname)s] %(message)s', level=DEFAULT_LOGGING_LEVEL) +logger = logging.getLogger(__name__) +logger.setLevel(DEFAULT_LOGGING_LEVEL) + +def start_build(resource_properties): + project_name = resource_properties.get('ProjectName') + if (not project_name): + raise ValueError( + 'missing ProjectName resource property' + ) + + response = codebuild_client.start_build( + projectName=project_name + ) + return response + +def handler(event, context): + logger.info('event: {}'.format(cfnresponse.json_dump_format(event))) + request_type = event.get('RequestType') + resource_properties = event.get('ResourceProperties') + + response = {} + response_status = cfnresponse.SUCCESS + request_id = '' + reason = '' + + if (request_type in ['Create', 'Update']): + try: + start_build_response = start_build(resource_properties) + logger.info( + 'start_build response: {}'.format( + cfnresponse.json_dump_format(start_build_response) + ) + ) + # only return specific fields to prevent "response object is too long" errors + response = { + 'build_id': start_build_response['build']['id'], + 'project_name': start_build_response['build']['projectName'], + 'arn': start_build_response['build']['arn'], + } + response_status = cfnresponse.SUCCESS + request_id = start_build_response['ResponseMetadata']['RequestId'] + reason = 'Create' + except Exception as e: + error = 'failed to start build: {}'.format(e) + logger.error(error) + response_status = cfnresponse.FAILED + reason = error + pass + + cfnresponse.send( + event, + context, + response_status, + response, + request_id, + reason + ) diff --git a/templates/custom-resources/requirements.txt b/templates/custom-resources/requirements.txt new file mode 100644 index 000000000..f8aed6c6e --- /dev/null +++ b/templates/custom-resources/requirements.txt @@ -0,0 +1,3 @@ +# Example requirements.txt +requests==2.23.0 +boto3==1.16.18 \ No newline at end of file diff --git a/templates/custom-resources/s3-cleanup.py b/templates/custom-resources/s3-cleanup.py new file mode 100644 index 000000000..c27385bd7 --- /dev/null +++ b/templates/custom-resources/s3-cleanup.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python + +########################################################################## +# Copyright 2017-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Amazon Software License (the "License"). You may not use this file +# except in compliance with the License. A copy of the License is located at +# +# http://aws.amazon.com/asl/ +# +# or in the "license" file accompanying this file. This file is distributed on an "AS IS" +# BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the +# License for the specific language governing permissions and limitations under the License. +########################################################################## +""" S3 Clean Up + +CloudFormation Custom Resource Lambda Function +""" + +import logging +import boto3 +import cfnresponse + +DEFAULT_LOGGING_LEVEL = logging.INFO +logging.basicConfig(format='[%(levelname)s] %(message)s', level=DEFAULT_LOGGING_LEVEL) +logger = logging.getLogger(__name__) +logger.setLevel(DEFAULT_LOGGING_LEVEL) + +boto3.set_stream_logger('boto3', level=DEFAULT_LOGGING_LEVEL) + +s3_client = boto3.client('s3') +s3_resource = boto3.resource('s3') + +def get_buckets_from_properties(resource_properties): + buckets = resource_properties.get('Buckets') + logger.info('buckets in properties {}'.format(buckets)) + if type(buckets) != list: + raise ValueError('invalid Buckets property type - not an array') + if not len(buckets): + raise ValueError('empty Buckets property') + for bucket in buckets: + bucket_type = type(bucket) + if not (bucket_type == str or bucket_type == unicode): + raise ValueError( + 'invalid bucket name type in Buckets property: {}'.format( + bucket_type + ) + ) + s3_client.head_bucket(Bucket=bucket) + + return buckets + +def delete_buckets(buckets): + for bucket in buckets: + bucket_resource = s3_resource.Bucket(bucket) + for object_version in bucket_resource.object_versions.all(): + object_version.delete() + for s3_object in bucket_resource.objects.all(): + s3_object.delete() + + bucket_resource.delete() + +def handler(event, context): + logger.info('event: {}'.format(cfnresponse.json_dump_format(event))) + request_type = event.get('RequestType') + resource_properties = event.get('ResourceProperties') + + response_status = cfnresponse.SUCCESS + response = {} + response_id = event.get('RequestId') + reason = '' + error = '' + + if (request_type == 'Delete'): + try: + buckets = get_buckets_from_properties(resource_properties) + delete_buckets(buckets) + logger.info('delete_buckets completed') + reason = 'Delete' + except Exception as e: + error = 'failed to delete buckets: {}'.format(e) + pass + + if error: + logger.error(error) + response_status = cfnresponse.FAILED + reason = error + + cfnresponse.send( + event, + context, + response_status, + response, + response_id, + reason + ) diff --git a/templates/lexbot.yaml b/templates/lexbot.yaml index 0feab58ae..db93792e1 100644 --- a/templates/lexbot.yaml +++ b/templates/lexbot.yaml @@ -426,6 +426,7 @@ Resources: QBusinessModelLayer: Type: "AWS::Lambda::LayerVersion" + Condition: EnableQBusiness Properties: Content: S3Bucket: !Ref SourceBucket diff --git a/templates/master-pipeline.yaml b/templates/master-pipeline.yaml deleted file mode 100644 index d98adbacb..000000000 --- a/templates/master-pipeline.yaml +++ /dev/null @@ -1,631 +0,0 @@ -AWSTemplateFormatVersion: 2010-09-09 -Description: | - Master Pipeline Lex Web UI CloudFormation template (v0.21.4) - The Lex Web Ui can be deployed to operate against either a Lex V2 Bot OR a Lex V1 Bot BUT NOT BOTH. - Please configure either the Lex V2 bot information OR the Lex V1 bot information and leave the other - version input parameters as defaulted. - A deployment of Lex Web Ui can not be switched between V2 and V1 by updating the stack with different parameters. - It deploys: - - S3 buckets to host the web application - - CodeBuild project to build the configuration and deploy to S3 - - Optional Lex Bot (based on OrderFlowers example) - - Optional Cognito Identity Pool for unauthenticated identities - - Optional Lambda function to delete S3 buckets - - CodeCommit Repository containg the source code in - this project and a CodeBuild project, Lambda functions to initialize - the repo - - Optional deployment pipeline using CodePipeline and CodeBuild - - CloudWatch Logs groups related to Lambda functions - - Associated IAM roles - -Parameters: - LexV2BotId: - Description: > - Bot ID (not bot name) of an existing Lex V2 Bot to be used by the web ui. NOTE: You must - also enter your Bot alias ID in the LexV2BotAliasId field below. DO NOT MODIFY this value if - configuring a V1 Bot. - Type: String - Default: '' - MaxLength: 50 - AllowedPattern: '(^$|^[a-zA-Z0-9]+((_[a-zA-Z0-9]+)*|([a-zA-Z0-9]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex V2 Bot name pattern. - - LexV2BotAliasId: - Description: > - Use your Lex V2 Bot's alias id (not alias name) here. DO NOT MODIFY this value if - configuring a V1 Bot. - Type: String - Default: '' - MinLength: 0 - MaxLength: 50 - AllowedPattern: '(^$|^[$a-zA-Z0-9]+((_[$a-zA-Z0-9]+)*|([$a-zA-Z0-9]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex V2 Alias name pattern. - - LexV2BotLocaleId: - Description: > - Specify your bot's supported locale ids. By default this list contains only en_US. Other Lex V2 - supported values are de_DE, en_AU, en_GB, es_419, es_ES, es_US, fr_CA, fr_FR, it_IT, ja_JP. A comma - separated list of values can be supplied with the first value in the list being the default value. The - remaining items can be selected in the Lex Web Ui menu. - See "https://docs.aws.amazon.com/lexv2/latest/dg/lex2.0.pdf" - for details on supported languages and locales. DO NOT MODIFY this value if - configuring a V1 Bot. - Type: String - Default: 'en_US' - MinLength: 2 - MaxLength: 50 - - BotName: - Description: > - Name of an existing Lex Bot to be used by the web ui. NOTE: You must - also enter your published bot alias in the BotAlias field below. DO NOT MODIFY this value if - configuring a V2 Bot. - Type: String - Default: '' - MinLength: 0 - MaxLength: 50 - AllowedPattern: '(^$|^[a-zA-Z]+((_[a-zA-Z]+)*|([a-zA-Z]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex Bot name pattern. - - BotAlias: - Description: > - WARNING: For production deployments, use your bot's published alias here. - The $LATEST alias should only be used for manual testing. Amazon Lex limits - the number of runtime requests that you can make to the $LATEST version of - the bot. DO NOT MODIFY this value if configuring a V2 Bot. - Type: String - Default: '$LATEST' - MinLength: 2 - MaxLength: 50 - AllowedPattern: '(^$|^[$a-zA-Z]+((_[$a-zA-Z]+)*|([$a-zA-Z]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex Alias name pattern. - - BotNamePrefix: - Type: String - Description: > - If Lex Version 2 BotId is left empty AND the Lex Version 1 BotName is left empty, - a Lex V1 Bot based on the OrderFlowers sample will be automatically created. - Specify a prefix to add to Lex resource names when using the sample bot. - Ignored if you provide your own bot. Must conform to the - permitted Lex Bot name syntax (alpha characters). - Default: WebUi - MinLength: 3 - MaxLength: 32 - AllowedPattern: '^[a-zA-Z\._]+$' - ConstraintDescription: > - Must conform with the permitted Lex Bot name pattern. - - ShouldDeleteBot: - Type: String - Default: true - AllowedValues: - - true - - false - Description: > - If set to True, the Optional Sample Lex bot and associated resources will - be deleted when the stack is deleted. Otherwise, the bot - will be preserved. Only applies if the bot is created by - this stack. - - ShouldEnableLiveChat: - Type: String - Default: false - AllowedValues: - - true - - false - Description: > - This is an optional parameter, if set to True, the AWS Connect live Chat functionality will be available. - A item to start a live chat will appear at the menu. - - ConnectContactFlowId: - Type: String - Description: > - Connect Contract Flow Id - Default: "" - - ConnectInstanceId: - Type: String - Description: > - Connect Instance Id - Default: "" - - ConnectPromptForNameMessage: - Type: String - Description: > - Message to display prompting the user for a name - Default: Before starting a live chat, please tell me your name? - - ConnectWaitForAgentMessage: - Type: String - Description: > - Message to display every message interval while waiting for an agent to connect - Default: Thanks for waiting. An agent will be with you when available. - - ConnectWaitForAgentMessageIntervalInSeconds: - Type: Number - Description: > - Interval in seconds between successive ConnectWaitForAgentMessage. 0 to disable interval. - Default: 60 - - ConnectAgentJoinedMessage: - Type: String - Description: > - Message to play when an agent joins the chat. {Agent} will be replaced with the Agent's name. - Default: "{Agent} has joined." - - ConnectAgentLeftMessage: - Type: String - Description: > - Message to play when an agent leaves the chat. {Agent} will be replaced with the Agent's name. - Default: "{Agent} has left." - - ConnectChatEndedMessage: - Type: String - Description: > - Message to play when a chat session has ended. - Default: "Chat ended." - - ConnectAttachChatTranscript: - Type: String - Default: false - AllowedValues: - - true - - false - Description: > - Attach chat transcript as file. This only works if you enable attachments in Amazon Connect. - - ConnectLiveChatTerms: - Type: String - Description: > - Command separated list of terms that can be used to start Live Chat mode - Default: "live chat" - - CodeCommitRepoName: - Type: String - Description: > - Name of CodeCommit repository to be created. Used as the - source for the pipeline and to automate deployments of the - web app. It is initialized with source artifacts from the - bootstrap S3 bucket. Must be unique per region. - Default: lex-web-ui - MinLength: 1 - MaxLength: 100 - AllowedPattern: '^[\w\.-]+$' - ConstraintDescription: Alphanumeric, dot and dash. - - CodePipelineName: - Type: String - Description: > - Name of CodePipeline pipeline to be created. Used to manage - the build and deployment of the web application. Must be - unique per region. - to true. - Default: lex-web-ui - MinLength: 1 - MaxLength: 100 - AllowedPattern: '[A-Za-z0-9.@\-_]+' - ConstraintDescription: Alphanumeric, dot, dash, underscore and @. - - CodeBuildName: - Type: String - Description: > - Name of the CodeBuild project to be created. Used for - building the web app with the pipeline. Must be unique - per region. - Default: lex-web-ui - MinLength: 2 - MaxLength: 255 - AllowedPattern: '^[A-Za-z0-9][A-Za-z0-9\-_]{1,254}$' - ConstraintDescription: > - Should start with Alphanumeric. May contain alphanumeric, undescore - and dash. - - WebAppParentOrigin: - Type: String - Description: > - Browser origin (e.g. http://mysite.example.com:8080) - of an existing site where you want to place the chat bot UI. - This is an optional parameter. If left empty, the sample parent page - will be hosted in the same S3 bucket as the iframe - Default: '' - AllowedPattern: '(^$|^https?://[\w\.-]+(:\d+)?$)' - ConstraintDescription: Empty or valid browser origin - - WebAppPath: - Type: String - Default: '/parent.html' - Description: > - Path to the page (or pages) under WebAppParentOrigin used to host - the chatbot UI. Multiple paths can be specified as a comma separated - list. - - CognitoIdentityPoolId: - Type: String - Description: > - Id of an existing Cognito Identity Pool. This is an optional - parameter. If left empty, a Cognito Identity Pool will be - automatically created. The pool ID is used by the web ui - to get AWS credentials for making calls to Lex and Polly. - Default: '' - AllowedPattern: '(^$|^[\w-]+:[0-9a-f-]+$)' - ConstraintDescription: Empty or a valid Cognito Identity Pool ID - - CognitoIdentityPoolName: - Type: String - Description: > - Name of Cognito identity pool to be created to provide - AWS credentials to the web ui. Only used if the - CognitoIdentityPoolId parameter is left empty (default). - Default: Lex Web UI - MinLength: 1 - MaxLength: 128 - AllowedPattern: '^[\w ]+$' - ConstraintDescription: Alphanumeric and spaces. - - CleanupBuckets: - Type: String - Default: true - AllowedValues: - - true - - false - Description: > - If set to True, buckets created for the Pipeline and to store the - web application will be deleted on CloudFormation stack delete. - If set to False, S3 buckets will be retained. - - # Sub-templates and source artifacts are hosted in this bucket. - # The content of this bucket is maintained outside of this template - # by using the Makefile under the build directory of this project. - # See the README.md file for instructions on how to use your own bucket. - BootstrapBucket: - Type: String - Default: aws-bigdata-blog - Description: > - S3 bucket containing pre-staged nested templates and source artifacts - BootstrapPrefix: - Type: String - Default: artifacts/aws-lex-web-ui/artifacts - Description: > - S3 prefix where the templates and source are stored under - - WebAppConfNegativeFeedback: - Type: String - Default: Thumbs down - Description: > - This optional parameter defines the message to be sent by the user upon pressing - a feedback button signaling a negative feedback. - If left empty feedback buttons will be disabled on the UI. - - WebAppConfPositiveFeedback: - Type: String - Default: Thumbs up - Description: > - This optional parameter defines the message to be sent by the user upon pressing - a feedback button signaling a positive feedback. - If left empty feedback buttons will be disabled on the UI. - - WebAppConfHelp: - Type: String - Default: Help - Description: > - This is an optional parameter, when defined with a value, a help button will display on the chat bot toolbar. - When pressed the button will send the entered string to the bot as a help message. If left empty - the help button will be disabled. - - WebAppConfCname: - Type: String - Default: "" - Description: This optional parameter allows a single CNAME to be defined and used as an alias to - the cloudfront distribution that is created by this template. If a CNAME is provided, a - WebAppAcmCertificateArn must also be provided. - - WebAppAcmCertificateArn: - Type: String - Default: "" - Description: This optional parameter allows a AcmCertificateArn to be provided for use in the Cloudfront - distribution created by this template. if a AcmCertificateArn is provided, a WebAppConfCname must also - be provided. - - WebAppWafAclArn: - Type: String - Default: "" - Description: This optional parameter allows a AWS WAF web ACL to be specified in ARN formation. This supports - AWS WAF V2. - - ConnectStartLiveChatLabel: - Type: String - Description: > - Label used in Menu to start connect live chat - Default: "Start Live Chat" - - ConnectStartLiveChatIcon: - Type: String - Description: > - Icon to use in menu to start connect live chat - Default: "people_alt" - - ConnectEndLiveChatLabel: - Type: String - Description: > - Label to use in menu and toolbar to end connect live chat - Default: "End Live Chat" - - ConnectEndLiveChatIcon: - Type: String - Description: > - Icon to use in menu and toolbar to end connect live chat - Default: "call_end" - - ConnectTranscriptMessageDelayInMsec: - Type: Number - Description: > - Delay to insert between each transcript message send to Connect in msec. - Default: 150 - -Rules: - ValidateEitherV1orV2: - RuleCondition: !Not - - !Equals - - !Ref BotName - - '' - Assertions: - - Assert: !Equals - - !Ref LexV2BotId - - '' - AssertDescription: 'Template cannot contain both Lex V1 and Lex V2 information' - -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: Deployment Parameters - Parameters: - - CodeBuildName - - CodePipelineName - - CodeCommitRepoName - - CleanupBuckets - - BootstrapBucket - - BootstrapPrefix - - Label: - default: Lex V1 Bot Configuration Parameters - Parameters: - - BotName - - BotAlias - - Label: - default: Lex V2 Bot Configuration Parameters - Parameters: - - LexV2BotId - - LexV2BotAliasId - - LexV2BotLocaleId - - Label: - default: Optional Sample Bot - Parameters: - - BotNamePrefix - - ShouldDeleteBot - - Label: - default: Cognito Parameters - Parameters: - - CognitoIdentityPoolId - - CognitoIdentityPoolName - - Label: - default: Web Application Parameters - Parameters: - - WebAppParentOrigin - - WebAppPath - - WebAppConfNegativeFeedback - - WebAppConfPositiveFeedback - - WebAppConfHelp - - WebAppConfCname - - WebAppAcmCertificateArn - - WebAppWafAclArn - - Label: - default: Connect Live Chat Parameters - Parameters: - - ShouldEnableLiveChat - - ConnectLiveChatTerms - - ConnectInstanceId - - ConnectContactFlowId - - ConnectPromptForNameMessage - - ConnectWaitForAgentMessage - - ConnectWaitForAgentMessageIntervalInSeconds - - ConnectAgentJoinedMessage - - ConnectAgentLeftMessage - - ConnectChatEndedMessage - - ConnectAttachChatTranscript - - ConnectStartLiveChatLabel - - ConnectStartLiveChatIcon - - ConnectEndLiveChatLabel - - ConnectEndLiveChatIcon -Conditions: - IsLexV2: !Not [ !Equals [!Ref LexV2BotId, ''] ] - NeedsBot: !And [ !Equals [!Ref BotName, ''], !Equals [!Ref LexV2BotId, ''] ] - NeedsCognito: !Equals [!Ref CognitoIdentityPoolId, ''] - NeedsParentOrigin: !Equals [!Ref WebAppParentOrigin, ''] - -Resources: - Bot: - Type: AWS::CloudFormation::Stack - Condition: NeedsBot - Properties: - TimeoutInMinutes: 15 - TemplateURL: !Sub "https://${BootstrapBucket}.s3.${AWS::Region}.amazonaws.com/${BootstrapPrefix}/templates/lexbot.yaml" - Parameters: - NamePrefix: !Ref BotNamePrefix - ShouldDeleteBot: !Ref ShouldDeleteBot - CustomResourceCodeBucket: !Ref BootstrapBucket - CustomResourceCodeObject: !Sub "${BootstrapPrefix}/custom-resources-v0.21.3.zip" - - CognitoIdentityPool: - Type: AWS::CloudFormation::Stack - Condition: NeedsCognito - Properties: - TemplateURL: !Sub "https://${BootstrapBucket}.s3.${AWS::Region}.amazonaws.com/${BootstrapPrefix}/templates/cognito.yaml" - Parameters: - CognitoIdentityPoolName: !Ref CognitoIdentityPoolName - LexBotName: - !If - - NeedsBot - - !GetAtt Bot.Outputs.BotName - - !Ref BotName - LexV2BotId: !Ref LexV2BotId - LexV2BotAliasId: !Ref LexV2BotAliasId - ShouldEnableLiveChat: !Ref ShouldEnableLiveChat - - ########################################################################## - # deployment using a pipeline - ########################################################################## - CodeCommitRepo: - Type: AWS::CloudFormation::Stack - Properties: - TimeoutInMinutes: 15 - TemplateURL: !Sub "https://${BootstrapBucket}.s3.${AWS::Region}.amazonaws.com/${BootstrapPrefix}/templates/coderepo.yaml" - Parameters: - BotName: - !If - - NeedsBot - - !GetAtt Bot.Outputs.BotName - - !Ref BotName - BotAlias: !Ref BotAlias - LexV2BotId: !Ref LexV2BotId - LexV2BotAliasId: !Ref LexV2BotAliasId - LexV2BotLocaleId: !Ref LexV2BotLocaleId - CodeBuildName: !Sub "${CodeCommitRepoName}-init" - CodeCommitRepoName: !Ref CodeCommitRepoName - CognitoIdentityPoolId: - !If - - NeedsCognito - - !GetAtt CognitoIdentityPool.Outputs.CognitoIdentityPoolId - - !Ref CognitoIdentityPoolId - SourceBucket: !Ref BootstrapBucket - SourceObject: !Sub "${BootstrapPrefix}/src-v0.21.4.zip" - CustomResourceCodeObject: !Sub "${BootstrapPrefix}/custom-resources-v0.21.3.zip" - - Pipeline: - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: !Sub "https://${BootstrapBucket}.s3.${AWS::Region}.amazonaws.com/${BootstrapPrefix}/templates/pipeline.yaml" - Parameters: - ResourcePrefix: !Ref "AWS::StackName" - BotName: - #!If - # - IsLexV2 - # - !Ref LexV2BotId - !If - - NeedsBot - - !GetAtt Bot.Outputs.BotName - - !Ref BotName - BotAlias: !Ref BotAlias - LexV2BotId: !Ref LexV2BotId - LexV2BotAliasId: !Ref LexV2BotAliasId - LexV2BotLocaleId: !Ref LexV2BotLocaleId - CodePipelineName: !Ref CodePipelineName - CodeCommitRepoName: !GetAtt CodeCommitRepo.Outputs.CodeCommitRepoName - CodeBuildName: !Ref CodeBuildName - CognitoIdentityPoolId: - !If - - NeedsCognito - - !GetAtt CognitoIdentityPool.Outputs.CognitoIdentityPoolId - - !Ref CognitoIdentityPoolId - ParentOrigin: !Ref WebAppParentOrigin - CustomResourceCodeBucket: !Ref BootstrapBucket - CustomResourceCodePrefix: !Ref BootstrapPrefix - CustomResourceCodeObject: !Sub "${BootstrapPrefix}/custom-resources-v0.21.3.zip" - InitiateChatLambdaCodeObject: !Sub "${BootstrapPrefix}/initiate-chat-lambda-v0.21.4.zip" - CleanupBuckets: !Ref CleanupBuckets - CognitoAppUserPoolClientId: - !If - - NeedsCognito - - !GetAtt CognitoIdentityPool.Outputs.CognitoUserPoolClientId - - '' - CognitoUserPoolId: - !If - - NeedsCognito - - !GetAtt CognitoIdentityPool.Outputs.CognitoUserPoolId - - '' - WebAppConfNegativeFeedback: !Ref WebAppConfNegativeFeedback - WebAppConfPositiveFeedback: !Ref WebAppConfPositiveFeedback - WebAppConfHelp: !Ref WebAppConfHelp - WebAppConfCname: !Ref WebAppConfCname - WebAppAcmCertificateArn: !Ref WebAppAcmCertificateArn - WebAppWafAclArn: !Ref WebAppWafAclArn - ShouldEnableLiveChat: !Ref ShouldEnableLiveChat - ConnectContactFlowId: !Ref ConnectContactFlowId - ConnectInstanceId: !Ref ConnectInstanceId - ConnectPromptForNameMessage: !Ref ConnectPromptForNameMessage - ConnectWaitForAgentMessage: !Ref ConnectWaitForAgentMessage - ConnectWaitForAgentMessageIntervalInSeconds: !Ref ConnectWaitForAgentMessageIntervalInSeconds - ConnectAgentJoinedMessage: !Ref ConnectAgentJoinedMessage - ConnectAgentLeftMessage: !Ref ConnectAgentLeftMessage - ConnectChatEndedMessage: !Ref ConnectChatEndedMessage - ConnectAttachChatTranscript: !Ref ConnectAttachChatTranscript - ConnectLiveChatTerms: !Ref ConnectLiveChatTerms - ConnectStartLiveChatLabel: !Ref ConnectStartLiveChatLabel - ConnectStartLiveChatIcon: !Ref ConnectStartLiveChatIcon - ConnectEndLiveChatLabel: !Ref ConnectEndLiveChatLabel - ConnectEndLiveChatIcon: !Ref ConnectEndLiveChatIcon - ConnectTranscriptMessageDelayInMsec: !Ref ConnectTranscriptMessageDelayInMsec - - CognitoIdentityPoolConfig: - Type: AWS::CloudFormation::Stack - Condition: NeedsCognito - Properties: - TemplateURL: !Sub "https://${BootstrapBucket}.s3.${AWS::Region}.amazonaws.com/${BootstrapPrefix}/templates/cognitouserpoolconfig.yaml" - Parameters: - CloudFrontUrl: !GetAtt Pipeline.Outputs.WebAppBase - WebAppUrl: !Ref WebAppParentOrigin - WebAppPath: !Ref WebAppPath - CodeBuildProjectName: !Ref CodeBuildName - CognitoUserPool: !GetAtt CognitoIdentityPool.Outputs.CognitoUserPoolId - CognitoUserPoolClient: !GetAtt CognitoIdentityPool.Outputs.CognitoUserPoolClientId - Timestamp: 1721061692 - -Outputs: - BotName: - Condition: NeedsBot - Description: > - Name of the Lex bot created by the stack - Value: !GetAtt Bot.Outputs.BotName - - CodeCommitRepoUrl: - Description: CodeCommit repository clone URL - Value: !GetAtt CodeCommitRepo.Outputs.CodeCommitRepoUrl - - PipelineUrl: - Description: > - Monitor the pipeline URL to see when the application has been fully - built and deployed. - Value: !Sub "https://console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${Pipeline.Outputs.PipelineName}" - - WebAppUrl: - Description: > - URL of the stand-alone sample web application. - This page will be available after the pipeline/deployment completes. - Value: !GetAtt Pipeline.Outputs.WebAppUrl - - ParentPageUrl: - Condition: NeedsParentOrigin - Description: > - URL of the iframe based sample web application - This page will be available after the pipeline/deployment completes. - Value: !GetAtt Pipeline.Outputs.ParentPageUrl - - LoaderScriptUrl: - Description: > - URL of the loader script - This script will be available after the pipeline/deployment completes. - Value: !GetAtt Pipeline.Outputs.LoaderScriptUrl - - SnippetUrl: - Description: > - URL of a page showing the snippet to load the chatbot UI as - an iframe - Value: !GetAtt Pipeline.Outputs.SnippetUrl - - CognitoIdentityPoolId: - Condition: NeedsCognito - Description: Cognito Identity Pool Id - Value: !GetAtt CognitoIdentityPool.Outputs.CognitoIdentityPoolId diff --git a/templates/master.yaml b/templates/master.yaml index c6172dd81..870b87456 100644 --- a/templates/master.yaml +++ b/templates/master.yaml @@ -1,6 +1,6 @@ AWSTemplateFormatVersion: 2010-09-09 Description: | - Master Lex Web UI CloudFormation template (v0.21.4) + Master Lex Web UI CloudFormation template (v0.21.5) The Lex Web Ui can be deployed to operate against either a Lex V2 Bot OR a Lex V1 Bot BUT NOT BOTH. Please configure either the Lex V2 bot information OR the Lex V1 bot information and leave the other version input parameters as defaulted. @@ -723,7 +723,7 @@ Resources: ParentStackName: !Ref "AWS::StackName" SourceBucket: !Ref BootstrapBucket QBusinessLambdaLayerObject: !Sub "${BootstrapPrefix}/layers.zip" - QBusinessLambdaCodeObject: !Sub "${BootstrapPrefix}/qbusiness-lambda-v0.21.4.zip" + QBusinessLambdaCodeObject: !Sub "${BootstrapPrefix}/qbusiness-lambda-v0.21.5.zip" AmazonQAppId: !Ref AmazonQAppId IDCApplicationARN: !Ref IDCApplicationARN @@ -764,10 +764,10 @@ Resources: CodeBuildName: !Ref CodeBuildName SourceBucket: !Ref BootstrapBucket SourcePrefix: !Ref BootstrapPrefix - SourceObject: !Sub "${BootstrapPrefix}/src-v0.21.4.zip" - CustomResourceCodeObject: !Sub "${BootstrapPrefix}/custom-resources-v0.21.3.zip" - InitiateChatLambdaCodeObject: !Sub "${BootstrapPrefix}/initiate-chat-lambda-v0.21.4.zip" - StreamingLambdaCodeObject: !Sub "${BootstrapPrefix}/streaming-lambda-v0.21.4.zip" + SourceObject: !Sub "${BootstrapPrefix}/src-v0.21.5.zip" + CustomResourceCodeObject: !Sub "${BootstrapPrefix}/custom-resources-v0.21.5.zip" + InitiateChatLambdaCodeObject: !Sub "${BootstrapPrefix}/initiate-chat-lambda-v0.21.5.zip" + StreamingLambdaCodeObject: !Sub "${BootstrapPrefix}/streaming-lambda-v0.21.5.zip" CleanupBuckets: !Ref CleanupBuckets BotName: !If @@ -860,7 +860,7 @@ Resources: AllowStreamingResponses: !Ref AllowStreamingResponses ShouldEnableUpload: !Ref ShouldEnableUpload UploadBucket: !Ref UploadBucket - Timestamp: 1721061692 + Timestamp: 1723566731 CognitoIdentityPoolConfig: Type: AWS::CloudFormation::Stack @@ -874,7 +874,7 @@ Resources: CodeBuildProjectName: !GetAtt CodeBuildDeploy.Outputs.CodeBuildProject CognitoUserPool: !GetAtt CognitoIdentityPool.Outputs.CognitoUserPoolId CognitoUserPoolClient: !GetAtt CognitoIdentityPool.Outputs.CognitoUserPoolClientId - Timestamp: 1721061692 + Timestamp: 1723566731 ########################################################################## # Lambda that will validate if user has put in an invalid CSS color/Hex string and fail deployment diff --git a/templates/pipeline.yaml b/templates/pipeline.yaml deleted file mode 100644 index c4d8ff5fa..000000000 --- a/templates/pipeline.yaml +++ /dev/null @@ -1,1006 +0,0 @@ -AWSTemplateFormatVersion: 2010-09-09 -Description: > - This template deploys a CI/CD pipeline used to build the Lex Web UI. - It deploys a CodePipeline pipeline, a CodeBuild project and and S3 buckets - to hold build artifacts and to host the application. It optionally deploys - a Lambda function to delete the S3 bucket. Additionally, it deploys the - related IAM roles needed for the stack. - -Parameters: - CodePipelineName: - Type: String - Description: Name of CodePipeline to be created. - Default: lex-web-ui - MinLength: 1 - MaxLength: 100 - AllowedPattern: '^[A-Za-z0-9.@\-_]+$' - ConstraintDescription: Alphanumeric, dot and dash. - - CodeCommitRepoName: - Type: String - Description: > - CodeCommit repository name to be used as the source of the - pipeline. - Default: lex-web-ui - MinLength: 1 - MaxLength: 100 - AllowedPattern: '^[\w\.-]+$' - ConstraintDescription: Alphanumeric, dot and dash. - - RepoBranchName: - Type: String - Description: > - CodeCommit repository branch name to be used as the source of the - pipeline. - Default: master - MinLength: 1 - MaxLength: 100 - AllowedPattern: '^[\w\.-]+$' - ConstraintDescription: Alphanumeric, dot and dash. - - CodeBuildName: - Type: String - Description: > - CodeBuild project to be created. Used for building the web app with - the pipeline. - Default: lex-web-ui - MinLength: 2 - MaxLength: 255 - AllowedPattern: '^[A-Za-z0-9][A-Za-z0-9\-_]{1,254}$' - ConstraintDescription: > - Should start with Alphanumeric. May contain alphanumeric, underscore - and dash. - - CognitoIdentityPoolId: - Type: String - Description: > - Cognito Identity Pool Id to used in the web app configuration. - MinLength: 1 - MaxLength: 55 - AllowedPattern: '^[\w-]+:[0-9a-f-]+$' - ConstraintDescription: > - Alphanumeric followed by a column and ending with a hex uuid type. - - CognitoAppUserPoolClientId: - Type: String - Description: > - Cognito App User Pool Client Id to used in the web app configuration. - - CognitoUserPoolId: - Type: String - Description: > - Cognito App User Pool Id - - LexV2BotId: - Description: > - Bot ID (not bot name) of an existing Lex V2 Bot to be used by the web ui. NOTE: You must - also enter your Bot alias ID in the LexV2BotAliasId field below. - Type: String - Default: '' - MinLength: 0 - MaxLength: 50 - AllowedPattern: '(^$|^[a-zA-Z0-9]+((_[a-zA-Z0-9]+)*|([a-zA-Z0-9]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex V2 Bot name pattern. - - LexV2BotAliasId: - Description: > - Use your Lex V2 bot's alias id (not alias name) here. - Type: String - Default: '' - MinLength: 0 - MaxLength: 50 - AllowedPattern: '(^$|^[$a-zA-Z0-9]+((_[$a-zA-Z0-9]+)*|([$a-zA-Z0-9]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex V2 Alias name pattern. - - LexV2BotLocaleId: - Description: > - Use your bot's locale id here. By default this is en_US. Lex V2 supported values are - en_AU, en_GB, es_419, es_ES, es_US, fr_CA, fr_FR, it_IT. - See "https://docs.aws.amazon.com/lexv2/latest/dg/lex2.0.pdf" - for details on supported languages and locales. - Type: String - Default: 'en_US' - MinLength: 2 - MaxLength: 50 - - BotName: - Description: > - Name of an existing Lex Bot to be used by the web ui. NOTE: You must - also enter your published bot alias in the BotAlias field below. DO NOT MODIFY this value if - configuring a V2 Bot. - Type: String - Default: '' - MinLength: 0 - MaxLength: 50 - AllowedPattern: '(^$|^[a-zA-Z]+((_[a-zA-Z]+)*|([a-zA-Z]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex Bot name pattern. - - BotAlias: - Description: > - WARNING: For production deployments, use your bot's published alias here. - The $LATEST alias should only be used for manual testing. Amazon Lex limits - the number of runtime requests that you can make to the $LATEST version of - the bot. DO NOT MODIFY this value if configuring a V2 Bot. - Type: String - Default: '$LATEST' - MinLength: 2 - MaxLength: 50 - AllowedPattern: '(^$|^[$a-zA-Z]+((_[$a-zA-Z]+)*|([$a-zA-Z]+_)*|_))' - ConstraintDescription: > - Must conform with the permitted Lex Alias name pattern. - - ParentOrigin: - Type: String - Description: > - Browser origin (e.g. http://mysite.example.com:8080) of an - existing site that is allowed to send/receive data and events - from the web ui in an iframe setup. This is an optional - parameter. If left empty, an S3 bucket will be created to - host a sample parent site embedding the webapp as an iframe. - AllowedPattern: '(^$|^https?://[\w\.-]+(:\d+)?$)' - ConstraintDescription: Empty or valid browser origin - - CleanupBuckets: - Type: String - Default: true - AllowedValues: - - true - - false - Description: > - If set to True, buckets and their associated data will be deleted on - CloudFormation stack delete. If set to False, S3 buckets will be retained. - - CustomResourceCodeBucket: - Type: String - Description: S3 bucket name for custom resource Lambda bundle - Default: tom-bootstrap-bucket - # Default: aws-bigdata-blog - - CustomResourceCodePrefix: - Type: String - Description: Prefix that identifies root of custom resources - Default: artifacts - - CustomResourceCodeObject: - Type: String - Description: > - S3 object zip file containing Lambda custom resource functions - Default: artifacts/aws-lex-web-ui/artifacts/custom-resources.zip - - InitiateChatLambdaCodeObject: - Type: String - Description: > - S3 object zip file containing Lambda custom resource functions - Default: artifacts/aws-lex-web-ui/artifacts/initiate-chat-lambda.zip - - WebAppConfNegativeFeedback: - Type: String - Default: Thumbs down - Description: > - This optional parameter defines the message to be sent by the user upon pressing - a feedback button signaling a negative feedback. - If left empty feedback buttons will be disabled on the UI. - - WebAppConfPositiveFeedback: - Type: String - Default: Thumbs up - Description: > - This optional parameter defines the message to be sent by the user upon pressing - a feedback button signaling a positive feedback. - If left empty feedback buttons will be disabled on the UI. - - WebAppConfHelp: - Type: String - Default: Help - Description: > - This is an optional parameter, when defined with a value, a help button will display on the chat bot toolbar. - When pressed the button will send the entered string to the bot as a help message. If left empty - the help button will be disabled. - - WebAppConfCname: - Type: String - Default: "" - Description: This optional parameter allows a single CNAME to be defined and used as an alias to - the cloudfront distribution that is created by this template. If a CNAME is provided, a - WebAppAcmCertificateArn must also be provided. - - WebAppAcmCertificateArn: - Type: String - Default: "" - Description: This optional parameter allows a AcmCertificateArn to be provided for use in the Cloudfront - distribution created by this template. if a AcmCertificateArn is provided, a WebAppConfCname must also - be provided. - - WebAppWafAclArn: - Type: String - Default: "" - Description: This optional parameter allows a AWS WAF web ACL to be specified in ARN formation. This supports - AWS WAF V2. - - ShouldEnableLiveChat: - Type: String - Default: false - AllowedValues: - - true - - false - Description: > - This is an optional parameter, if set to True, the AWS Connect live Chat functionality will be available. - A item to start a live chat will appear at the menu. - - ConnectContactFlowId: - Type: String - Description: > - Connect Contract Flow Id - - ConnectInstanceId: - Type: String - Description: > - Connect Instance Id - Default: "" - - ConnectPromptForNameMessage: - Type: String - Description: > - Message to display prompting the user for a name - Default: Before starting a live chat, please tell me your name? - - ConnectWaitForAgentMessage: - Type: String - Description: > - Message to display every message interval while waiting for an agent to connect - Default: Thanks for waiting. An agent will be with you when available. - - ConnectWaitForAgentMessageIntervalInSeconds: - Type: Number - Description: > - Interval in seconds between successive ConnectWaitForAgentMessage. 0 to disable interval. - Default: 60 - - ConnectAgentJoinedMessage: - Type: String - Description: > - Message to play when an agent joins the chat. {Agent} will be replaced with the Agent's name. - Default: "{Agent} has joined." - - ConnectAgentLeftMessage: - Type: String - Description: > - Message to play when an agent leaves the chat. {Agent} will be replaced with the Agent's name. - Default: "{Agent} has left." - - ConnectChatEndedMessage: - Type: String - Description: > - Message to play when a chat session has ended. - Default: "Chat ended." - - ConnectAttachChatTranscript: - Type: String - Default: true - AllowedValues: - - true - - false - Description: > - Attach chat transcript as file. This only works if you enable - - ConnectLiveChatTerms: - Type: String - Description: > - Command separated list of terms that can be used to start Live Chat mode - Default: "live chat" - - ConnectStartLiveChatLabel: - Type: String - Description: > - Label used in Menu to start connect live chat - Default: "Start Live Chat" - - ConnectStartLiveChatIcon: - Type: String - Description: > - Icon to use in menu to start connect live chat - Default: "people_alt" - - ConnectEndLiveChatLabel: - Type: String - Description: > - Label to use in menu and toolbar to end connect live chat - Default: "End Live Chat" - - ConnectEndLiveChatIcon: - Type: String - Description: > - Icon to use in menu and toolbar to end connect live chat - Default: "call_end" - - ConnectTranscriptMessageDelayInMsec: - Type: Number - Description: > - Delay to insert between each transcript message send to Connect in msec. - Default: 150 - - ResourcePrefix: - Type: String - Description: > - This will be a prefix for resources that must have unique names. - -Conditions: - NeedsParentOrigin: !Equals [!Ref ParentOrigin, ''] - ShouldCleanupBuckets: !Equals [!Ref CleanupBuckets, true] - EnableLiveChat: !Equals [!Ref ShouldEnableLiveChat, true] - UseDefaultCloudfrontUrl: !Or [ !Equals [!Ref WebAppConfCname, ''], !Equals [!Ref WebAppAcmCertificateArn, ''] ] - ShouldNotSpecifyWafAcl: !Equals [!Ref WebAppWafAclArn, ''] - -Resources: - # Bucket where S3 access logs are stored - S3ServerAccessLogs: - Type: AWS::S3::Bucket - UpdateReplacePolicy: Retain - DeletionPolicy: Retain - Properties: - VersioningConfiguration: - Status: Enabled - BucketEncryption: - ServerSideEncryptionConfiguration: - - ServerSideEncryptionByDefault: - SSEAlgorithm: AES256 - - S3ServerAccessLogsBucketPolicy: - Type: "AWS::S3::BucketPolicy" - Properties: - Bucket: - Ref: "S3ServerAccessLogs" - PolicyDocument: - Statement: - - Effect: "Allow" - Action: - - "s3:PutObject" - Resource: - - !Sub "arn:aws:s3:::${S3ServerAccessLogs}/*" - Principal: - Service: "logging.s3.amazonaws.com" - Condition: - ArnLike: - aws:SourceArn: - - !Sub "arn:aws:s3:::${WebAppBucket}" - StringEquals: - aws:SourceAccount: - - !Sub "${AWS::AccountId}" - - # Artifact Bucket used by CodePipeline and CodBuild - ArtifactStore: - Type: AWS::S3::Bucket - UpdateReplacePolicy: Retain - DeletionPolicy: Retain - Properties: - VersioningConfiguration: - Status: Enabled - LoggingConfiguration: - DestinationBucketName: !Ref S3ServerAccessLogs - LogFilePrefix: "artifactstore/" - BucketEncryption: - ServerSideEncryptionConfiguration: - - ServerSideEncryptionByDefault: - SSEAlgorithm: AES256 - - # Bucket where the web app is deployed - WebAppBucket: - Type: AWS::S3::Bucket - UpdateReplacePolicy: Retain - DeletionPolicy: Retain - Properties: - WebsiteConfiguration: - IndexDocument: index.html - VersioningConfiguration: - Status: Enabled - LoggingConfiguration: - DestinationBucketName: !Ref S3ServerAccessLogs - LogFilePrefix: "webappbucket/" - BucketEncryption: - ServerSideEncryptionConfiguration: - - ServerSideEncryptionByDefault: - SSEAlgorithm: AES256 - CorsConfiguration: - !If - - NeedsParentOrigin - - !Ref AWS::NoValue - - CorsRules: - - AllowedMethods: - - GET - AllowedOrigins: - - !Ref ParentOrigin - - WebAppBucketOriginAccessIdentity: - Type: AWS::CloudFront::CloudFrontOriginAccessIdentity - Properties: - CloudFrontOriginAccessIdentityConfig: - Comment: !Sub "access-identity-${WebAppBucket}" - - WebAppBucketBucketPolicy: - Type: "AWS::S3::BucketPolicy" - Properties: - Bucket: - Ref: "WebAppBucket" - PolicyDocument: - Statement: - - Effect: "Allow" - Action: - - "s3:GetObject" - Resource: - - !Sub "arn:aws:s3:::${WebAppBucket}/*" - Principal: - CanonicalUser: !GetAtt WebAppBucketOriginAccessIdentity.S3CanonicalUserId - - # Bucket for CloudFrontDistributionLogs - LexWebUiCloudFrontDistributionLogsBucket: - Type: AWS::S3::Bucket - UpdateReplacePolicy: Retain - DeletionPolicy: Retain - Properties: - OwnershipControls: - Rules: - - ObjectOwnership: BucketOwnerPreferred - VersioningConfiguration: - Status: Enabled - BucketEncryption: - ServerSideEncryptionConfiguration: - - ServerSideEncryptionByDefault: - SSEAlgorithm: AES256 - - LexWebUIResponseHeaderPolicy: - Type : "AWS::CloudFront::ResponseHeadersPolicy" - Properties: - ResponseHeadersPolicyConfig: - Comment: "Response header policy for LexWebUI" - Name: !Join ["-", [!Ref ResourcePrefix, "LexWebUIResponseHeaderPolicy"]] - CorsConfig: - AccessControlAllowOrigins: - Items: - - !If - - NeedsParentOrigin - - "*" - - !Ref ParentOrigin - AccessControlAllowHeaders: - Items: - - "*" - AccessControlAllowMethods: - Items: - - "GET" - AccessControlAllowCredentials: False - AccessControlMaxAgeSec: 600 - OriginOverride: true - SecurityHeadersConfig: - XSSProtection: - Override: False - Protection: True - ModeBlock: True - ReferrerPolicy: - Override: False - ReferrerPolicy: "strict-origin-when-cross-origin" - ContentTypeOptions: - Override: false - StrictTransportSecurity: - Override: False - IncludeSubdomains: True - Preload: False - AccessControlMaxAgeSec: 47304000 - - #cloudfront distribution - LexWebUiDistribution: - Type: AWS::CloudFront::Distribution - DependsOn: - - WebAppBucket - Properties: - DistributionConfig: - Origins: - - DomainName: !Sub "${WebAppBucket}.s3.${AWS::Region}.amazonaws.com" - S3OriginConfig: - OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${WebAppBucketOriginAccessIdentity}" - Id: webuiorigin - Enabled: true - Comment: cloudfront distribution for lex-web-ui - DefaultRootObject: index.html - Logging: - Bucket: !GetAtt LexWebUiCloudFrontDistributionLogsBucket.DomainName - IncludeCookies: true - Prefix: "lexwebui/" - CustomErrorResponses: - # Send errors to index file - # TODO move TTL to mapping or parameter - - ErrorCachingMinTTL: 300 - ErrorCode: 403 - ResponseCode: 200 - ResponsePagePath: /index.html - - ErrorCachingMinTTL: 300 - ErrorCode: 404 - ResponseCode: 200 - ResponsePagePath: /index.html - DefaultCacheBehavior: - AllowedMethods: - - GET - - HEAD - - OPTIONS - CachedMethods: - - GET - - HEAD - - OPTIONS - Compress: true - TargetOriginId: webuiorigin - CachePolicyId: "658327ea-f89d-4fab-a63d-7e88639e58f6" - OriginRequestPolicyId: "88a5eaf4-2fd4-4709-b370-b4c650ea3fcf" - ViewerProtocolPolicy: redirect-to-https - ResponseHeadersPolicyId: !GetAtt LexWebUIResponseHeaderPolicy.Id - Aliases: - !If - - UseDefaultCloudfrontUrl - - !Ref AWS::NoValue - - [ !Ref WebAppConfCname ] - ViewerCertificate: - !If - - UseDefaultCloudfrontUrl - - CloudFrontDefaultCertificate: true - - AcmCertificateArn: !Ref WebAppAcmCertificateArn - MinimumProtocolVersion: TLSv1.2_2018 - SslSupportMethod: sni-only - WebACLId: - !If - - ShouldNotSpecifyWafAcl - - !Ref AWS::NoValue - - !Ref WebAppWafAclArn - HttpVersion: http2 - IPV6Enabled: true - - # Bucket where the test parent page is hosted - ParentPageBucket: - Type: AWS::S3::Bucket - Condition: NeedsParentOrigin - UpdateReplacePolicy: Retain - DeletionPolicy: Retain - Properties: - WebsiteConfiguration: - IndexDocument: index.html - VersioningConfiguration: - Status: Enabled - LoggingConfiguration: - DestinationBucketName: !Ref S3ServerAccessLogs - LogFilePrefix: "parentpagebucket/" - BucketEncryption: - ServerSideEncryptionConfiguration: - - ServerSideEncryptionByDefault: - SSEAlgorithm: AES256 - - RestApi: - Type: AWS::CloudFormation::Stack - Condition: EnableLiveChat - Properties: - TimeoutInMinutes: 15 - TemplateURL: !Sub "https://${CustomResourceCodeBucket}.s3.${AWS::Region}.amazonaws.com/${CustomResourceCodePrefix}/templates/restapi.yaml" - Parameters: - ParentStackName: !Ref "AWS::StackName" - SourceBucket: !Ref CustomResourceCodeBucket - InitiateChatLambdaCodeObject: !Ref InitiateChatLambdaCodeObject - ConnectContactFlowId: !Ref ConnectContactFlowId - ConnectInstanceId: !Ref ConnectInstanceId - ParentOrigin: !Sub "https://${LexWebUiDistribution.DomainName}" - - CodeBuild: - Type: AWS::CodeBuild::Project - Properties: - Name: !Ref CodeBuildName - Description: Used to build the Lex Web UI - ServiceRole: !GetAtt CodeBuildRole.Arn - TimeoutInMinutes: 30 - Artifacts: - Type: CODEPIPELINE - Environment: - Type: LINUX_CONTAINER - Image: aws/codebuild/amazonlinux2-x86_64-standard:2.0 - ComputeType: BUILD_GENERAL1_SMALL - EnvironmentVariables: - - Name: BUILD_TYPE - Value: full - - Name: POOL_ID - Value: !Ref CognitoIdentityPoolId - - Name: ENABLE_LIVE_CHAT - Value: !Ref ShouldEnableLiveChat - - Name: CONNECT_CONTACT_FLOW_ID - Value: !Ref ConnectContactFlowId - - Name: CONNECT_INSTANCE_ID - Value: !Ref ConnectInstanceId - - Name: CONNECT_API_GATEWAY_ENDPOINT - Value: !If [EnableLiveChat, !Sub "https://${RestApi.Outputs.RestApiId}.execute-api.${AWS::Region}.amazonaws.com/Prod/livechat", ""] - - Name: CONNECT_PROMPT_FOR_NAME_MESSAGE - Value: !Ref ConnectPromptForNameMessage - - Name: CONNECT_WAIT_FOR_AGENT_MESSAGE - Value: !Ref ConnectWaitForAgentMessage - - Name: CONNECT_WAIT_FOR_AGENT_MESSAGE_INTERVAL_IN_SECONDS - Value: !Ref ConnectWaitForAgentMessageIntervalInSeconds - - Name: CONNECT_LIVE_CHAT_TERMS - Value: !Ref ConnectLiveChatTerms - - Name: CONNECT_AGENT_JOINED_MESSAGE - Value: !Ref ConnectAgentJoinedMessage - - Name: CONNECT_AGENT_LEFT_MESSAGE - Value: !Ref ConnectAgentLeftMessage - - Name: CONNECT_CHAT_ENDED_MESSAGE - Value: !Ref ConnectChatEndedMessage - - Name: CONNECT_ATTACH_CHAT_TRANSCRIPT - Value: !Ref ConnectAttachChatTranscript - - Name: CONNECT_START_LIVE_CHAT_LABEL - Value: !Ref ConnectStartLiveChatLabel - - Name: CONNECT_START_LIVE_CHAT_ICON - Value: !Ref ConnectStartLiveChatIcon - - Name: CONNECT_END_LIVE_CHAT_LABEL - Value: !Ref ConnectEndLiveChatLabel - - Name: CONNECT_END_LIVE_CHAT_ICON - Value: !Ref ConnectEndLiveChatIcon - - Name: CONNECT_TRANSCRIPT_MESSAGE_DELAY_IN_MSEC - Value: !Ref ConnectTranscriptMessageDelayInMsec - - Name: APP_USER_POOL_CLIENT_ID - Value: !Ref CognitoAppUserPoolClientId - - Name: APP_USER_POOL_NAME - Value: !Ref CognitoUserPoolId - - Name: WEBAPP_BUCKET - Value: !Ref WebAppBucket - - Name: AWS_DEFAULT_REGION - Value: !Sub "${AWS::Region}" - - Name: V2_BOT_ID - Value: !Ref LexV2BotId - - Name: V2_BOT_ALIAS_ID - Value: !Ref LexV2BotAliasId - - Name: V2_BOT_LOCALE_ID - Value: !Ref LexV2BotLocaleId - - Name: BOT_NAME - Value: !Ref BotName - - Name: BOT_ALIAS - Value: !Ref BotAlias - - Name: PARENT_ORIGIN - Value: !If - - NeedsParentOrigin - - !Sub "https://${LexWebUiDistribution.DomainName}" - - !Ref ParentOrigin - - Name: IFRAME_ORIGIN - Value: !Sub "https://${LexWebUiDistribution.DomainName}" - - Name: NEGATIVE_INTENT - Value: !Ref WebAppConfNegativeFeedback - - Name: POSITIVE_INTENT - Value: !Ref WebAppConfPositiveFeedback - - Name: HELP_INTENT - Value: !Ref WebAppConfHelp - - Source: - Type: CODEPIPELINE - BuildSpec: !Sub | - version: 0.1 - phases: - install: - commands: - - make install-deps - pre_build: - commands: - - aws configure set region "$AWS_DEFAULT_REGION" - - cp src/config/default-lex-web-ui-loader-config.json src/config/lex-web-ui-loader-config.json - - make config - build: - commands: - - make build - post_build: - commands: - - make sync-website - - aws cloudfront create-invalidation --distribution-id "${LexWebUiDistribution}" --paths '/*' - - CodeBuildRole: - Type: AWS::IAM::Role - Properties: - Path: / - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Principal: - Service: - - codebuild.amazonaws.com - Effect: Allow - Action: - - sts:AssumeRole - Policies: - - PolicyName: CloudFrontInvalidateDistribution - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - cloudfront:CreateInvalidation - Resource: "*" - - PolicyName: CloudWatchLogsCodeBuild - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - logs:CreateLogGroup - - logs:CreateLogStream - - logs:PutLogEvents - Resource: - - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildName}" - - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildName}:*" - - PolicyName: S3ReadWrite - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - s3:Get* - - s3:Head* - - s3:List* - - s3:CreateMultipartUpload - - s3:CompleteMultipartUpload - - s3:AbortMultipartUpload - - s3:CopyObject - - s3:PutObject* - - s3:DeleteObject* - - s3:Upload* - Resource: - - !Sub "arn:aws:s3:::${ArtifactStore}" - - !Sub "arn:aws:s3:::${ArtifactStore}/*" - - !Sub "arn:aws:s3:::${WebAppBucket}" - - !Sub "arn:aws:s3:::${WebAppBucket}/*" - - !If - - NeedsParentOrigin - - !Sub "arn:aws:s3:::${ParentPageBucket}" - - !Ref AWS::NoValue - - !If - - NeedsParentOrigin - - !Sub "arn:aws:s3:::${ParentPageBucket}/*" - - !Ref AWS::NoValue - - PolicyName: PollySynthesizeSpeech - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - polly:SynthesizeSpeech - Resource: "*" - - PolicyName: TranslateText - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - translate:TranslateText - - comprehend:DetectDominantLanguage - Resource: "*" - CodePipeline: - Type: AWS::CodePipeline::Pipeline - Properties: - Name: !Ref CodePipelineName - ArtifactStore: - Type: S3 - Location: !Ref ArtifactStore - RoleArn: !GetAtt CodePipelineRole.Arn - Stages: - - Name: Source - Actions: - - Name: CodeCommitRepo - ActionTypeId: - Category: Source - Owner: AWS - Version: 1 - Provider: CodeCommit - OutputArtifacts: - - Name: SourceOutput - Configuration: - RepositoryName: !Ref CodeCommitRepoName - BranchName: !Ref RepoBranchName - RunOrder: 1 - - Name: BuildDeploy - Actions: - - Name: WebApp - InputArtifacts: - - Name: SourceOutput - ActionTypeId: - Category: Build - Owner: AWS - Version: 1 - Provider: CodeBuild - Configuration: - ProjectName: !Ref CodeBuild - RunOrder: 1 - - CodePipelineRole: - Type: AWS::IAM::Role - Properties: - Path: / - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Principal: - Service: - - codepipeline.amazonaws.com - Effect: Allow - Action: - - sts:AssumeRole - Policies: - - PolicyName: CodeCommit - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - codecommit:GetBranch - - codecommit:GetCommit - - codecommit:UploadArchive - - codecommit:GetUploadArchiveStatus - - codecommit:CancelUploadArchive - Resource: - - !Sub "arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${CodeCommitRepoName}" - - PolicyName: S3ReadWrite - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - s3:Get* - - s3:Head* - - s3:List* - - s3:CreateMultipartUpload - - s3:CompleteMultipartUpload - - s3:AbortMultipartUpload - - s3:CopyObject - - s3:PutObject* - - s3:DeleteObject* - - s3:Upload* - Resource: - - !Sub "arn:aws:s3:::${ArtifactStore}" - - !Sub "arn:aws:s3:::${ArtifactStore}/*" - - PolicyName: CodeBuildStart - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - codebuild:BatchGetBuilds - - codebuild:StartBuild - Resource: !GetAtt CodeBuild.Arn - - # custom resource to cleanup S3 buckets - S3Cleanup: - Type: Custom::S3Cleanup - Condition: ShouldCleanupBuckets - Properties: - ServiceToken: !GetAtt S3CleanupLambda.Arn - Buckets: - - !Ref ArtifactStore - - !Ref WebAppBucket - - !If - - NeedsParentOrigin - - !Ref ParentPageBucket - - !Ref AWS::NoValue - - # Lambda function for custom resource - S3CleanupLambda: - Type: AWS::Lambda::Function - Condition: ShouldCleanupBuckets - Properties: - Code: - S3Bucket: !Ref CustomResourceCodeBucket - S3Key: !Ref CustomResourceCodeObject - Handler: s3-cleanup.handler - Role: !GetAtt S3CleanupLambdaRole.Arn - Runtime: python3.10 - Timeout: 120 - TracingConfig: - Mode: Active - - S3CleanupLambdaRole: - Type: AWS::IAM::Role - Condition: ShouldCleanupBuckets - Properties: - Path: / - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Principal: - Service: - - lambda.amazonaws.com - Effect: Allow - Action: - - sts:AssumeRole - Policies: - - PolicyName: LogsForLambda - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - logs:CreateLogGroup - - logs:CreateLogStream - - logs:PutLogEvents - Resource: - - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*" - - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*:*" - - PolicyName: S3All - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - s3:* - Resource: - - !Sub "arn:aws:s3:::${ArtifactStore}" - - !Sub "arn:aws:s3:::${ArtifactStore}/*" - - !Sub "arn:aws:s3:::${WebAppBucket}" - - !Sub "arn:aws:s3:::${WebAppBucket}/*" - - !If - - NeedsParentOrigin - - !Sub "arn:aws:s3:::${ParentPageBucket}" - - !Ref AWS::NoValue - - !If - - NeedsParentOrigin - - !Sub "arn:aws:s3:::${ParentPageBucket}/*" - - !Ref AWS::NoValue - - PolicyName: XRay - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - xray:PutTraceSegments - - xray:PutTelemetryRecords - Resource: "*" - - PolicyName: AllowVPCSupport - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - ec2:DescribeNetworkInterfaces - - ec2:CreateNetworkInterface - - ec2:DeleteNetworkInterface - Resource: "*" - - PolicyName: LambdaUpgrades - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - lambda:UpdateFunctionCode - Resource: "*" - -Outputs: - PipelineName: - Value: !Ref CodePipeline - Description: Name of CodePipeline pipeline - - WebAppUrl: - Value: !Sub "https://${LexWebUiDistribution.DomainName}/index.html" - Description: URL of the web application - - WebAppBase: - Value: !Sub "https://${LexWebUiDistribution.DomainName}" - Description: Base url portion of the web application - - WebAppDomainName: - Value: !Sub "${LexWebUiDistribution.DomainName}" - Description: DomainName of the web application - - ParentPageUrl: - Value: !Sub "https://${LexWebUiDistribution.DomainName}/parent.html" - Description: URL of the sample parent page - Condition: NeedsParentOrigin - - LoaderScriptUrl: - Value: !Sub "https://${LexWebUiDistribution.DomainName}/lex-web-ui-loader.min.js" - Description: URL of the loader script - Condition: NeedsParentOrigin - - SnippetUrl: - Value: !Sub "https://${LexWebUiDistribution.DomainName}/iframe-snippet.html" - Description: URL of a page showing the snippet to load the chatbot UI as an iframe - Condition: NeedsParentOrigin - - RestApiId: - Value: !Sub "${RestApi.Outputs.RestApiId}" - Description: Rest API ID if required by other elements - Condition: EnableLiveChat