From a82e7a9c9feb26e6ea117f1aede6dce37813095f Mon Sep 17 00:00:00 2001 From: Harini Gunabalan Date: Thu, 27 Feb 2020 14:57:46 +0100 Subject: [PATCH] OpenSAP course officesupplies --- packages/bookshop-enhanced/app/index.cds | 1 - packages/bookshop-enhanced/db/schema.cds | 25 -- packages/bookshop-enhanced/package.json | 29 -- packages/bookshop-enhanced/srv/services.cds | 9 - packages/bookshop-enhanced/srv/services.js | 30 -- packages/bookshop-enhanced/tests/genres.http | 33 -- packages/bookshop-enhanced/tests/reviews.http | 32 -- packages/bookshop/app/_i18n/i18n.properties | 13 - .../bookshop/app/_i18n/i18n_de.properties | 13 - packages/bookshop/app/admin/fiori-service.cds | 37 -- .../bookshop/app/admin/webapp/Component.js | 22 -- .../app/admin/webapp/i18n/i18n.properties | 11 - .../bookshop/app/admin/webapp/manifest.json | 128 ------- .../bookshop/app/browse/fiori-service.cds | 47 --- .../bookshop/app/browse/webapp/Component.js | 22 -- .../app/browse/webapp/i18n/i18n.properties | 11 - .../bookshop/app/browse/webapp/manifest.json | 106 ------ packages/bookshop/app/common.cds | 74 ---- packages/bookshop/app/fiori.html | 55 --- packages/bookshop/app/index.cds | 8 - .../bookshop/app/orders/fiori-service.cds | 118 ------ .../bookshop/app/orders/webapp/Component.js | 22 -- .../app/orders/webapp/i18n/i18n.properties | 11 - .../bookshop/app/orders/webapp/manifest.json | 170 --------- .../db/data/sap.capire.bookshop-Authors.csv | 5 - .../db/data/sap.capire.bookshop-Books.csv | 6 - .../data/sap.capire.bookshop-Books_texts.csv | 4 - .../data/sap.capire.bookshop-OrderItems.csv | 4 - .../db/data/sap.capire.bookshop-Orders.csv | 3 - .../db/data/sap.common-Currencies.csv | 7 - .../db/data/sap.common-Currencies_texts.csv | 13 - packages/bookshop/db/schema.cds | 35 -- packages/bookshop/package.json | 21 -- packages/bookshop/srv/admin-service.cds | 7 - packages/bookshop/srv/cat-service.cds | 13 - packages/bookshop/srv/cat-service.js | 26 -- packages/bookshop/tests/bookshop.http | 18 - packages/bookshop/tests/orders.http | 18 - .../db/data/sap.capire.bookstore-Authors.csv | 5 - .../data/sap.capire.products-Categories.csv | 11 - .../db/data/sap.capire.products-Products.csv | 6 - .../sap.capire.products-Products_texts.csv | 4 - packages/bookstore/db/schema.cds | 18 - packages/bookstore/package.json | 48 --- packages/bookstore/srv/_workarounds.cds | 12 - packages/bookstore/srv/services.cds | 35 -- packages/bookstore/srv/services.js | 38 -- packages/bookstore/tests/books.cds | 7 - .../bookstore/tests/localized-data.test.js | 190 ---------- packages/common-contacts/db/code-lists.cds | 37 -- .../db/data/sap.capire.contacts-Countries.csv | 12 - .../sap.capire.contacts-Countries_texts.csv | 12 - packages/common-contacts/db/schema.cds | 58 --- packages/common-contacts/index.cds | 2 - packages/common-contacts/package.json | 10 - packages/common-contacts/readme.md | 67 ---- packages/common-contacts/srv/code-lists.js | 70 ---- .../common-contacts/tests/code-lists.test.js | 68 ---- packages/common-contacts/tests/index.cds | 11 - .../data/sap.common-Currencies.csv | 12 - .../data/sap.common-Currencies_texts.csv | 13 - packages/common-currencies/index.cds | 17 - packages/common-currencies/package.json | 10 - packages/media-server/db/data-model.cds | 13 - packages/media-server/index.cds | 2 - packages/media-server/package.json | 24 -- packages/media-server/srv/media-service.cds | 8 - packages/media-server/srv/media-service.js | 68 ---- packages/officesupplies/.eslintrc | 24 ++ packages/officesupplies/.gitignore | 23 ++ packages/officesupplies/.vscode/cds.js | 4 + packages/officesupplies/.vscode/launch.json | 19 + packages/officesupplies/.vscode/settings.json | 7 + packages/officesupplies/.vscode/tasks.json | 23 ++ packages/officesupplies/README.md | 25 ++ packages/officesupplies/app/products/.npmrc | 4 + .../officesupplies/app/products/README.md | 21 ++ .../officesupplies/app/products/package.json | 33 ++ packages/officesupplies/app/products/ui5.yaml | 4 + .../app/products/webapp/Component.js | 10 + .../app/products/webapp/WEB-INF/web.xml | 118 ++++++ .../app/products/webapp/i18n/i18n.properties | 9 + .../app/products/webapp/index.html | 38 ++ .../products/webapp/localService/metadata.xml | 233 ++++++++++++ .../app/products/webapp/manifest.json | 133 +++++++ .../officesupplies/app/products/xs-app.json | 16 + packages/officesupplies/app/suppliers/.npmrc | 4 + .../officesupplies/app/suppliers/README.md | 21 ++ .../officesupplies/app/suppliers/package.json | 33 ++ .../officesupplies/app/suppliers/ui5.yaml | 4 + .../app/suppliers/webapp/Component.js | 10 + .../app/suppliers/webapp/WEB-INF/web.xml | 118 ++++++ .../app/suppliers/webapp/i18n/i18n.properties | 9 + .../app/suppliers/webapp/index.html | 38 ++ .../webapp/localService/metadata.xml | 346 ++++++++++++++++++ .../app/suppliers/webapp/manifest.json | 155 ++++++++ .../officesupplies/app/suppliers/xs-app.json | 16 + .../sap.capire.officesupplies-Products.csv | 7 + .../sap.capire.officesupplies-Suppliers.csv | 16 + .../db/csv/sap.common-Currencies.csv | 5 + packages/officesupplies/db/schema.cds | 30 ++ packages/officesupplies/i18n/i18n.properties | 19 + packages/officesupplies/images/box.png | Bin 0 -> 12307 bytes packages/officesupplies/images/envelopes.png | Bin 0 -> 11128 bytes packages/officesupplies/images/eraser.png | Bin 0 -> 42706 bytes packages/officesupplies/images/hanger1.png | Bin 0 -> 16286 bytes packages/officesupplies/images/hanger2.png | Bin 0 -> 15956 bytes packages/officesupplies/images/hanger3.png | Bin 0 -> 16013 bytes packages/officesupplies/images/hanger4.png | Bin 0 -> 16317 bytes packages/officesupplies/images/magnets.png | Bin 0 -> 37782 bytes packages/officesupplies/images/mug.png | Bin 0 -> 18063 bytes packages/officesupplies/images/pen.png | Bin 0 -> 20974 bytes packages/officesupplies/package.json | 14 + packages/officesupplies/srv/cat-service.cds | 71 ++++ .../db/data/sap.capire.orders-OrderItems.csv | 4 - .../db/data/sap.capire.orders-Orders.csv | 3 - packages/orders-service/db/schema.cds | 15 - packages/orders-service/index.cds | 2 - packages/orders-service/package.json | 11 - .../orders-service/srv/orders-service.cds | 6 - packages/products-service/db/schema.cds | 18 - packages/products-service/index.cds | 2 - packages/products-service/package.json | 16 - .../products-service/srv/admin-service.cds | 7 - .../products-service/tests/categories.test.js | 68 ---- .../data/sap.capire.products-Categories.csv | 10 - packages/products-service/tests/postman.json | 157 -------- packages/reviews-service/db/schema.cds | 31 -- packages/reviews-service/index.cds | 1 - packages/reviews-service/package.json | 30 -- .../reviews-service/srv/reviews-service.cds | 41 --- .../reviews-service/srv/reviews-service.js | 41 --- .../reviews-service/tests/messaging.test.js | 69 ---- packages/users-service/index.cds | 1 - packages/users-service/package.json | 12 - packages/users-service/srv/services.cds | 7 - 136 files changed, 1660 insertions(+), 2647 deletions(-) delete mode 100644 packages/bookshop-enhanced/app/index.cds delete mode 100644 packages/bookshop-enhanced/db/schema.cds delete mode 100644 packages/bookshop-enhanced/package.json delete mode 100644 packages/bookshop-enhanced/srv/services.cds delete mode 100644 packages/bookshop-enhanced/srv/services.js delete mode 100644 packages/bookshop-enhanced/tests/genres.http delete mode 100644 packages/bookshop-enhanced/tests/reviews.http delete mode 100644 packages/bookshop/app/_i18n/i18n.properties delete mode 100644 packages/bookshop/app/_i18n/i18n_de.properties delete mode 100644 packages/bookshop/app/admin/fiori-service.cds delete mode 100644 packages/bookshop/app/admin/webapp/Component.js delete mode 100644 packages/bookshop/app/admin/webapp/i18n/i18n.properties delete mode 100644 packages/bookshop/app/admin/webapp/manifest.json delete mode 100644 packages/bookshop/app/browse/fiori-service.cds delete mode 100644 packages/bookshop/app/browse/webapp/Component.js delete mode 100644 packages/bookshop/app/browse/webapp/i18n/i18n.properties delete mode 100644 packages/bookshop/app/browse/webapp/manifest.json delete mode 100644 packages/bookshop/app/common.cds delete mode 100644 packages/bookshop/app/fiori.html delete mode 100644 packages/bookshop/app/index.cds delete mode 100644 packages/bookshop/app/orders/fiori-service.cds delete mode 100644 packages/bookshop/app/orders/webapp/Component.js delete mode 100644 packages/bookshop/app/orders/webapp/i18n/i18n.properties delete mode 100644 packages/bookshop/app/orders/webapp/manifest.json delete mode 100644 packages/bookshop/db/data/sap.capire.bookshop-Authors.csv delete mode 100644 packages/bookshop/db/data/sap.capire.bookshop-Books.csv delete mode 100644 packages/bookshop/db/data/sap.capire.bookshop-Books_texts.csv delete mode 100644 packages/bookshop/db/data/sap.capire.bookshop-OrderItems.csv delete mode 100644 packages/bookshop/db/data/sap.capire.bookshop-Orders.csv delete mode 100644 packages/bookshop/db/data/sap.common-Currencies.csv delete mode 100644 packages/bookshop/db/data/sap.common-Currencies_texts.csv delete mode 100644 packages/bookshop/db/schema.cds delete mode 100644 packages/bookshop/package.json delete mode 100644 packages/bookshop/srv/admin-service.cds delete mode 100644 packages/bookshop/srv/cat-service.cds delete mode 100644 packages/bookshop/srv/cat-service.js delete mode 100644 packages/bookshop/tests/bookshop.http delete mode 100644 packages/bookshop/tests/orders.http delete mode 100644 packages/bookstore/db/data/sap.capire.bookstore-Authors.csv delete mode 100644 packages/bookstore/db/data/sap.capire.products-Categories.csv delete mode 100644 packages/bookstore/db/data/sap.capire.products-Products.csv delete mode 100644 packages/bookstore/db/data/sap.capire.products-Products_texts.csv delete mode 100644 packages/bookstore/db/schema.cds delete mode 100644 packages/bookstore/package.json delete mode 100644 packages/bookstore/srv/_workarounds.cds delete mode 100644 packages/bookstore/srv/services.cds delete mode 100644 packages/bookstore/srv/services.js delete mode 100644 packages/bookstore/tests/books.cds delete mode 100644 packages/bookstore/tests/localized-data.test.js delete mode 100644 packages/common-contacts/db/code-lists.cds delete mode 100644 packages/common-contacts/db/data/sap.capire.contacts-Countries.csv delete mode 100644 packages/common-contacts/db/data/sap.capire.contacts-Countries_texts.csv delete mode 100644 packages/common-contacts/db/schema.cds delete mode 100644 packages/common-contacts/index.cds delete mode 100644 packages/common-contacts/package.json delete mode 100644 packages/common-contacts/readme.md delete mode 100644 packages/common-contacts/srv/code-lists.js delete mode 100644 packages/common-contacts/tests/code-lists.test.js delete mode 100644 packages/common-contacts/tests/index.cds delete mode 100644 packages/common-currencies/data/sap.common-Currencies.csv delete mode 100644 packages/common-currencies/data/sap.common-Currencies_texts.csv delete mode 100644 packages/common-currencies/index.cds delete mode 100644 packages/common-currencies/package.json delete mode 100644 packages/media-server/db/data-model.cds delete mode 100644 packages/media-server/index.cds delete mode 100644 packages/media-server/package.json delete mode 100644 packages/media-server/srv/media-service.cds delete mode 100644 packages/media-server/srv/media-service.js create mode 100644 packages/officesupplies/.eslintrc create mode 100644 packages/officesupplies/.gitignore create mode 100644 packages/officesupplies/.vscode/cds.js create mode 100644 packages/officesupplies/.vscode/launch.json create mode 100644 packages/officesupplies/.vscode/settings.json create mode 100644 packages/officesupplies/.vscode/tasks.json create mode 100644 packages/officesupplies/README.md create mode 100644 packages/officesupplies/app/products/.npmrc create mode 100644 packages/officesupplies/app/products/README.md create mode 100644 packages/officesupplies/app/products/package.json create mode 100644 packages/officesupplies/app/products/ui5.yaml create mode 100644 packages/officesupplies/app/products/webapp/Component.js create mode 100644 packages/officesupplies/app/products/webapp/WEB-INF/web.xml create mode 100644 packages/officesupplies/app/products/webapp/i18n/i18n.properties create mode 100644 packages/officesupplies/app/products/webapp/index.html create mode 100644 packages/officesupplies/app/products/webapp/localService/metadata.xml create mode 100644 packages/officesupplies/app/products/webapp/manifest.json create mode 100644 packages/officesupplies/app/products/xs-app.json create mode 100644 packages/officesupplies/app/suppliers/.npmrc create mode 100644 packages/officesupplies/app/suppliers/README.md create mode 100644 packages/officesupplies/app/suppliers/package.json create mode 100644 packages/officesupplies/app/suppliers/ui5.yaml create mode 100644 packages/officesupplies/app/suppliers/webapp/Component.js create mode 100644 packages/officesupplies/app/suppliers/webapp/WEB-INF/web.xml create mode 100644 packages/officesupplies/app/suppliers/webapp/i18n/i18n.properties create mode 100644 packages/officesupplies/app/suppliers/webapp/index.html create mode 100644 packages/officesupplies/app/suppliers/webapp/localService/metadata.xml create mode 100644 packages/officesupplies/app/suppliers/webapp/manifest.json create mode 100644 packages/officesupplies/app/suppliers/xs-app.json create mode 100644 packages/officesupplies/db/csv/sap.capire.officesupplies-Products.csv create mode 100644 packages/officesupplies/db/csv/sap.capire.officesupplies-Suppliers.csv create mode 100644 packages/officesupplies/db/csv/sap.common-Currencies.csv create mode 100644 packages/officesupplies/db/schema.cds create mode 100644 packages/officesupplies/i18n/i18n.properties create mode 100644 packages/officesupplies/images/box.png create mode 100644 packages/officesupplies/images/envelopes.png create mode 100644 packages/officesupplies/images/eraser.png create mode 100644 packages/officesupplies/images/hanger1.png create mode 100644 packages/officesupplies/images/hanger2.png create mode 100644 packages/officesupplies/images/hanger3.png create mode 100644 packages/officesupplies/images/hanger4.png create mode 100644 packages/officesupplies/images/magnets.png create mode 100644 packages/officesupplies/images/mug.png create mode 100644 packages/officesupplies/images/pen.png create mode 100644 packages/officesupplies/package.json create mode 100644 packages/officesupplies/srv/cat-service.cds delete mode 100644 packages/orders-service/db/data/sap.capire.orders-OrderItems.csv delete mode 100644 packages/orders-service/db/data/sap.capire.orders-Orders.csv delete mode 100644 packages/orders-service/db/schema.cds delete mode 100644 packages/orders-service/index.cds delete mode 100644 packages/orders-service/package.json delete mode 100644 packages/orders-service/srv/orders-service.cds delete mode 100644 packages/products-service/db/schema.cds delete mode 100644 packages/products-service/index.cds delete mode 100644 packages/products-service/package.json delete mode 100644 packages/products-service/srv/admin-service.cds delete mode 100644 packages/products-service/tests/categories.test.js delete mode 100644 packages/products-service/tests/data/sap.capire.products-Categories.csv delete mode 100644 packages/products-service/tests/postman.json delete mode 100644 packages/reviews-service/db/schema.cds delete mode 100644 packages/reviews-service/index.cds delete mode 100644 packages/reviews-service/package.json delete mode 100644 packages/reviews-service/srv/reviews-service.cds delete mode 100644 packages/reviews-service/srv/reviews-service.js delete mode 100644 packages/reviews-service/tests/messaging.test.js delete mode 100644 packages/users-service/index.cds delete mode 100644 packages/users-service/package.json delete mode 100644 packages/users-service/srv/services.cds diff --git a/packages/bookshop-enhanced/app/index.cds b/packages/bookshop-enhanced/app/index.cds deleted file mode 100644 index 1674468e..00000000 --- a/packages/bookshop-enhanced/app/index.cds +++ /dev/null @@ -1 +0,0 @@ -using from '@sap/capire-bookshop/app'; diff --git a/packages/bookshop-enhanced/db/schema.cds b/packages/bookshop-enhanced/db/schema.cds deleted file mode 100644 index d6adb541..00000000 --- a/packages/bookshop-enhanced/db/schema.cds +++ /dev/null @@ -1,25 +0,0 @@ -/* - In this model we demonstrate how to add Genres to Books in - as if it was an external extension. For example we use - CDS Aspects' to extend the core domain model's Books entity - as well as the AdminService. - */ - -namespace sap.capire.bookshop; -using { sap.capire.reviews.ReviewsService as external } from '@sap/capire-reviews'; -using { sap.capire.bookshop.Books } from '@sap/capire-bookshop/db/schema'; -using { sap.common.CodeList } from '@sap/cds/common'; - -// Extending Books by Reviews and Genres -extend Books with { - reviews : Composition of many external.Reviews on reviews.subject = ID; - rating : external.Reviews.rating; - genre : Association to Genres; -} - -// Hierarchical Code List for Genres -entity Genres : CodeList { - key ID : Integer; - children : Composition of many Genres on children.parent = $self; - parent : Association to Genres; -} diff --git a/packages/bookshop-enhanced/package.json b/packages/bookshop-enhanced/package.json deleted file mode 100644 index 94c0ae7e..00000000 --- a/packages/bookshop-enhanced/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "@sap/capire-bookshop-enhanced", - "version": "1.0.0", - "description": "A sample for extending a base application package, in this case bookshop, e.g. in context of verticalization or customization.", - "repository": "https://github.com/SAP-samples/cloud-cap-samples.git", - "license": "SAP SAMPLE CODE LICENSE", - "dependencies": { - "@sap/capire-bookshop": "^1.0.0", - "@sap/capire-reviews": "^1.0.0", - "@sap/cds": "latest", - "express": "*" - }, - "scripts": { - "reviews-service": "PORT=5005 cds run ../reviews-service --bind --in-memory?", - "start": "cds run --in-memory?", - "watch": "cds watch" - }, - "cds": { - "requires": { - "sap.capire.reviews.ReviewsService": { - "kind": "odata", - "model": "@sap/capire-reviews" - }, - "messaging": { - "kind": "file-based-messaging" - } - } - } -} diff --git a/packages/bookshop-enhanced/srv/services.cds b/packages/bookshop-enhanced/srv/services.cds deleted file mode 100644 index 7ff9f9af..00000000 --- a/packages/bookshop-enhanced/srv/services.cds +++ /dev/null @@ -1,9 +0,0 @@ -namespace sap.capire.bookshop; - -using { AdminService } from '@sap/capire-bookshop/srv/admin-service'; -using { sap.capire.bookshop } from '../db/schema'; - -@impl:'srv/services' -extend service AdminService with { - entity Genres as projection on bookshop.Genres; -} diff --git a/packages/bookshop-enhanced/srv/services.js b/packages/bookshop-enhanced/srv/services.js deleted file mode 100644 index 24503d49..00000000 --- a/packages/bookshop-enhanced/srv/services.js +++ /dev/null @@ -1,30 +0,0 @@ -const cds = require ('@sap/cds') - -module.exports = cds.service.impl (async()=>{ - - const ReviewsService = await cds.connect.to ('sap.capire.reviews.ReviewsService') - const CatalogService = await cds.connect.to ('CatalogService') - const db = await cds.connect.to ('db') - // import model definitions from connected services to work with subsequently - const { Books } = db.entities - const { Reviews } = ReviewsService.entities - - CatalogService.impl (srv => { - // delegate requests to read reviews to ReviewsService - srv.on ('READ', 'Books/reviews', (req) => { - const [ subject ] = req.params - const tx = ReviewsService.transaction (req) - return tx.run (SELECT.from (Reviews) .where ({subject})) - }) - }) - - // react on event messages from reviews service - ReviewsService.on ('reviewed', (msg) => { - console.debug ('> received:', msg.event, msg.data) - const { subject, rating } = msg.data - const tx = db // TODO: db.transaction (msg) - return tx.run (UPDATE (Books, subject) .with ({rating})) - // return tx.update (Books, subject) .with ({rating}) - }) - -}) diff --git a/packages/bookshop-enhanced/tests/genres.http b/packages/bookshop-enhanced/tests/genres.http deleted file mode 100644 index aecd8777..00000000 --- a/packages/bookshop-enhanced/tests/genres.http +++ /dev/null @@ -1,33 +0,0 @@ -################################################# -# -# Genres -# - -GET http://localhost:4004/admin/Genres? -### - -POST http://localhost:4004/admin/Genres? -Content-Type: application/json - -{ "ID":100, "name":"Some Sample Genres...", "children":[ - { "ID":101, "name":"Cat", "children":[ - { "ID":102, "name":"Kitty", "children":[ - { "ID":103, "name":"Kitty Cat", "children":[ - { "ID":104, "name":"Aristocat" } ]}, - { "ID":105, "name":"Kitty Bat" } ]}, - { "ID":106, "name":"Catwoman", "children":[ - { "ID":107, "name":"Catalina" } ]} ]}, - { "ID":108, "name":"Catweazle" } -]} -### - -GET http://localhost:4004/admin/Genres(100)? -# &$expand=children -# &$expand=children($expand=children($expand=children($expand=children))) -### - -DELETE http://localhost:4004/admin/Genres(103) -### - -DELETE http://localhost:4004/admin/Genres(100) -### diff --git a/packages/bookshop-enhanced/tests/reviews.http b/packages/bookshop-enhanced/tests/reviews.http deleted file mode 100644 index 21206196..00000000 --- a/packages/bookshop-enhanced/tests/reviews.http +++ /dev/null @@ -1,32 +0,0 @@ -################################################# -# -# Reviews Service -# - - -### Use this one for ReviewsService running as a separate process -# Note: use 5005 instead of 4004 in case of separate service -POST http://localhost:5005/reviews/Reviews -# POST http://localhost:4004/reviews/Reviews -Content-Type: application/json;IEEE754Compatible=true - -{"subject":"201", "rating":"5", "title":"boo"} - -### Direct Request to ReviewsService -# Note: use 5005 instead of 4004 in case of separate service -GET http://localhost:5005/reviews/Reviews? -# GET http://localhost:4004/reviews/Reviews? -# &$filter=subject eq '201' - - -### Request to CatalogService > delegated to ReviewsService -GET http://localhost:4004/browse/Books(201)/reviews - -### Alternative OData URL -GET http://localhost:4004/browse/Books/201/reviews - -### -GET http://localhost:4004/browse/Books(201)? -&$select=ID,title,rating -# &$expand=reviews -# Note: the latter only works in case of ReviewsService in same process diff --git a/packages/bookshop/app/_i18n/i18n.properties b/packages/bookshop/app/_i18n/i18n.properties deleted file mode 100644 index 5d6f03d6..00000000 --- a/packages/bookshop/app/_i18n/i18n.properties +++ /dev/null @@ -1,13 +0,0 @@ -Books = Books -Book = Book -ID = ID -Title = Title -Author = Author -AuthorID = Author ID -Stock = Stock -Name = Name -AuthorName = Author's Name -Authors = Authors -Order = Order -Orders = Orders -Price = Price diff --git a/packages/bookshop/app/_i18n/i18n_de.properties b/packages/bookshop/app/_i18n/i18n_de.properties deleted file mode 100644 index 365b45df..00000000 --- a/packages/bookshop/app/_i18n/i18n_de.properties +++ /dev/null @@ -1,13 +0,0 @@ -Books = Bücher -Book = Buch -ID = ID -Title = Titel -Authors = Autoren -Author = Autor -AuthorID = ID des Autors -AuthorName = Name des Autors -Name = Name -Stock = Bestand -Order = Bestellung -Orders = Bestellungen -Price = Preis diff --git a/packages/bookshop/app/admin/fiori-service.cds b/packages/bookshop/app/admin/fiori-service.cds deleted file mode 100644 index 5fd19df0..00000000 --- a/packages/bookshop/app/admin/fiori-service.cds +++ /dev/null @@ -1,37 +0,0 @@ -using AdminService from '../../srv/admin-service'; - -//////////////////////////////////////////////////////////////////////////// -// -// Books Object Page -// -annotate AdminService.Books with @( - UI: { - Facets: [ - {$Type: 'UI.ReferenceFacet', Label: '{i18n>General}', Target: '@UI.FieldGroup#General'}, - {$Type: 'UI.ReferenceFacet', Label: '{i18n>Details}', Target: '@UI.FieldGroup#Details'}, - {$Type: 'UI.ReferenceFacet', Label: '{i18n>Admin}', Target: '@UI.FieldGroup#Admin'}, - ], - FieldGroup#General: { - Data: [ - {Value: title}, - {Value: author_ID}, - {Value: descr}, - ] - }, - FieldGroup#Details: { - Data: [ - {Value: stock}, - {Value: price}, - {Value: currency_code, Label: '{i18n>Currency}'}, - ] - }, - FieldGroup#Admin: { - Data: [ - {Value: createdBy}, - {Value: createdAt}, - {Value: modifiedBy}, - {Value: modifiedAt} - ] - } - } -); diff --git a/packages/bookshop/app/admin/webapp/Component.js b/packages/bookshop/app/admin/webapp/Component.js deleted file mode 100644 index 9fdf2d05..00000000 --- a/packages/bookshop/app/admin/webapp/Component.js +++ /dev/null @@ -1,22 +0,0 @@ -sap.ui.define(["sap/fe/AppComponent"], ac => ac.extend("admin.Component", { - metadata:{ manifest:'json' } -})) - -// sap.ui.define (["sap/ui/core/UIComponent"], ui5 => ui5.extend("bookshop.Component", { -// metadata: { manifest: "json" } -// })) -// sap.ui.define (["sap/ui/generic/app/AppComponent"], ui5 => ui5.extend("bookshop.Component", { -// metadata: { manifest: "json" } -// })) - -// jQuery.sap.declare("bookshop.Component"); -// sap.ui.getCore().loadLibrary("sap.ui.generic.app"); -// jQuery.sap.require("sap.ui.generic.app.AppComponent"); - -// sap.ui.generic.app.AppComponent.extend("bookshop.Component", { -// metadata: { -// manifest: "json" -// } -// }); - -/* eslint no-undef:0 */ \ No newline at end of file diff --git a/packages/bookshop/app/admin/webapp/i18n/i18n.properties b/packages/bookshop/app/admin/webapp/i18n/i18n.properties deleted file mode 100644 index 28b03dff..00000000 --- a/packages/bookshop/app/admin/webapp/i18n/i18n.properties +++ /dev/null @@ -1,11 +0,0 @@ -# This is the resource bundle of itelo -# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459 - -# JCI app descriptor contains lower case TITLE -appTitle=Bookshop Sample - -# JCI app descriptor contains lower case DESCRIPTION -appSubTitle=CAP Sample Application - -# JCI app descriptor contains lower case DESCRIPTION -appDescription=CDS Sample Service diff --git a/packages/bookshop/app/admin/webapp/manifest.json b/packages/bookshop/app/admin/webapp/manifest.json deleted file mode 100644 index 574480f1..00000000 --- a/packages/bookshop/app/admin/webapp/manifest.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "_version": "1.8.0", - "sap.app": { - "id": "admin", - "type": "application", - "title": "Manage Books", - "description": "Sample Application", - "i18n": "i18n/i18n.properties", - "dataSources": { - "AdminService": { - "uri": "/admin/", - "type": "OData", - "settings": { - "odataVersion": "4.0" - } - } - }, - "-sourceTemplate": { - "id": "ui5template.basicSAPUI5ApplicationProject", - "-id": "ui5template.smartTemplate", - "-version": "1.40.12" - } - }, - "sap.ui5": { - "dependencies": { - "libs": { - "sap.fe": {} - } - }, - "models": { - "i18n": { - "type": "sap.ui.model.resource.ResourceModel", - "uri": "i18n/i18n.properties" - }, - "": { - "dataSource": "AdminService", - "settings": { - "synchronizationMode": "None", - "operationMode": "Server", - "autoExpandSelect" : true, - "earlyRequests": true, - "groupProperties": { - "default": { - "submit": "Auto" - } - } - } - } - }, - "routing": { - "routes": [ - { - "pattern": ":?query:", - "name": "BooksList", - "target": "BooksList" - }, - { - "pattern": "Books({key}):?query:", - "name": "BooksDetails", - "target": "BooksDetails" - }, - { - "pattern": "Books({key}/author({key2}):?query:", - "name": "AuthorsDetails", - "target": "AuthorsDetails" - } - ], - "targets": { - "BooksList": { - "type": "Component", - "id": "BooksList", - "name": "sap.fe.templates.ListReport", - "options": { - "settings" : { - "entitySet" : "Books", - "navigation" : { - "Books" : { - "detail" : { - "route" : "BooksDetails" - } - } - } - } - } - }, - "BooksDetails": { - "type": "Component", - "id": "BooksDetailsList", - "name": "sap.fe.templates.ObjectPage", - "options": { - "settings" : { - "entitySet" : "Books", - "navigation" : { - "Authors" : { - "detail" : { - "route" : "AuthorsDetails" - } - } - } - } - } - }, - "AuthorsDetails": { - "type": "Component", - "id": "AuthorsDetailsList", - "name": "sap.fe.templates.ObjectPage", - "options": { - "settings" : { - "entitySet" : "Authors" - } - } - } - } - }, - "contentDensities": { - "compact": true, - "cozy": true - } - }, - "sap.ui": { - "technology": "UI5", - "fullWidth": false - }, - "sap.fiori": { - "registrationIds": [], - "archeType": "transactional" - } -} \ No newline at end of file diff --git a/packages/bookshop/app/browse/fiori-service.cds b/packages/bookshop/app/browse/fiori-service.cds deleted file mode 100644 index d0d12da3..00000000 --- a/packages/bookshop/app/browse/fiori-service.cds +++ /dev/null @@ -1,47 +0,0 @@ -using CatalogService from '../../srv/cat-service'; - -//////////////////////////////////////////////////////////////////////////// -// -// Books Object Page -// -annotate CatalogService.Books with @( - UI: { - HeaderInfo: { - Description: {Value: author} - }, - HeaderFacets: [ - {$Type: 'UI.ReferenceFacet', Label: '{i18n>Description}', Target: '@UI.FieldGroup#Descr'}, - ], - Facets: [ - {$Type: 'UI.ReferenceFacet', Label: '{i18n>Details}', Target: '@UI.FieldGroup#Price'}, - ], - FieldGroup#Descr: { - Data: [ - {Value: descr}, - ] - }, - FieldGroup#Price: { - Data: [ - {Value: price}, - {Value: currency.symbol, Label: '{i18n>Currency}'}, - ] - }, - } -); - - -//////////////////////////////////////////////////////////////////////////// -// -// Books Object Page -// -annotate CatalogService.Books with @( - UI: { - SelectionFields: [ ID, price, currency_code ], - LineItem: [ - {Value: title}, - {Value: author, Label:'{i18n>Author}'}, - {Value: price}, - {Value: currency.symbol, Label:' '}, - ] - }, -); diff --git a/packages/bookshop/app/browse/webapp/Component.js b/packages/bookshop/app/browse/webapp/Component.js deleted file mode 100644 index e46ce759..00000000 --- a/packages/bookshop/app/browse/webapp/Component.js +++ /dev/null @@ -1,22 +0,0 @@ -sap.ui.define(["sap/fe/AppComponent"], ac => ac.extend("bookshop.Component", { - metadata:{ manifest:'json' } -})) - -// sap.ui.define (["sap/ui/core/UIComponent"], ui5 => ui5.extend("bookshop.Component", { -// metadata: { manifest: "json" } -// })) -// sap.ui.define (["sap/ui/generic/app/AppComponent"], ui5 => ui5.extend("bookshop.Component", { -// metadata: { manifest: "json" } -// })) - -// jQuery.sap.declare("bookshop.Component"); -// sap.ui.getCore().loadLibrary("sap.ui.generic.app"); -// jQuery.sap.require("sap.ui.generic.app.AppComponent"); - -// sap.ui.generic.app.AppComponent.extend("bookshop.Component", { -// metadata: { -// manifest: "json" -// } -// }); - -/* eslint no-undef:0 */ \ No newline at end of file diff --git a/packages/bookshop/app/browse/webapp/i18n/i18n.properties b/packages/bookshop/app/browse/webapp/i18n/i18n.properties deleted file mode 100644 index 28b03dff..00000000 --- a/packages/bookshop/app/browse/webapp/i18n/i18n.properties +++ /dev/null @@ -1,11 +0,0 @@ -# This is the resource bundle of itelo -# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459 - -# JCI app descriptor contains lower case TITLE -appTitle=Bookshop Sample - -# JCI app descriptor contains lower case DESCRIPTION -appSubTitle=CAP Sample Application - -# JCI app descriptor contains lower case DESCRIPTION -appDescription=CDS Sample Service diff --git a/packages/bookshop/app/browse/webapp/manifest.json b/packages/bookshop/app/browse/webapp/manifest.json deleted file mode 100644 index 4212312e..00000000 --- a/packages/bookshop/app/browse/webapp/manifest.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "_version": "1.8.0", - "sap.app": { - "id": "bookshop", - "type": "application", - "title": "Browse Books", - "description": "Sample Application", - "i18n": "i18n/i18n.properties", - "dataSources": { - "CatalogService": { - "uri": "/browse/", - "type": "OData", - "settings": { - "odataVersion": "4.0" - } - } - }, - "-sourceTemplate": { - "id": "ui5template.basicSAPUI5ApplicationProject", - "-id": "ui5template.smartTemplate", - "-version": "1.40.12" - } - }, - "sap.ui5": { - "dependencies": { - "libs": { - "sap.fe": {} - } - }, - "models": { - "i18n": { - "type": "sap.ui.model.resource.ResourceModel", - "uri": "i18n/i18n.properties" - }, - "": { - "dataSource": "CatalogService", - "settings": { - "synchronizationMode": "None", - "operationMode": "Server", - "autoExpandSelect": true, - "earlyRequests": true, - "groupProperties": { - "default": { - "submit": "Auto" - } - } - } - } - }, - "routing": { - "routes": [ - { - "pattern": ":?query:", - "name": "BooksList", - "target": "BooksList" - }, - { - "pattern": "Books({key}):?query:", - "name": "BooksDetails", - "target": "BooksDetails" - } - ], - "targets": { - "BooksList": { - "type": "Component", - "id": "BooksList", - "name": "sap.fe.templates.ListReport", - "options": { - "settings": { - "entitySet": "Books", - "navigation": { - "Books": { - "detail": { - "route": "BooksDetails" - } - } - } - } - } - }, - "BooksDetails": { - "type": "Component", - "id": "BooksDetailsList", - "name": "sap.fe.templates.ObjectPage", - "options": { - "settings": { - "entitySet": "Books" - } - } - } - } - }, - "contentDensities": { - "compact": true, - "cozy": true - } - }, - "sap.ui": { - "technology": "UI5", - "fullWidth": false - }, - "sap.fiori": { - "registrationIds": [], - "archeType": "transactional" - } -} diff --git a/packages/bookshop/app/common.cds b/packages/bookshop/app/common.cds deleted file mode 100644 index 309daaf5..00000000 --- a/packages/bookshop/app/common.cds +++ /dev/null @@ -1,74 +0,0 @@ -/* - Common Annotations shared by all apps -*/ - -using { sap.capire.bookshop as my } from '../db/schema'; - - -//////////////////////////////////////////////////////////////////////////// -// -// Books Lists -// -annotate my.Books with @( - UI: { - Identification: [{Value:title}], - SelectionFields: [ ID, author_ID, price, currency_code ], - LineItem: [ - {Value: ID}, - {Value: title}, - {Value: author.name, Label:'{i18n>Author}'}, - {Value: stock}, - {Value: price}, - {Value: currency.symbol, Label:' '}, - ] - } -) { - author @ValueList.entity:'Authors'; -}; - -annotate my.Authors with @( - UI: { - Identification: [{Value:name}], - } -); - - -//////////////////////////////////////////////////////////////////////////// -// -// Books Details -// -annotate my.Books with @( - UI: { - HeaderInfo: { - TypeName: '{i18n>Book}', - TypeNamePlural: '{i18n>Books}', - Title: {Value: title}, - Description: {Value: author.name} - }, - } -); - - - -//////////////////////////////////////////////////////////////////////////// -// -// Books Elements -// -annotate my.Books with { - ID @title:'{i18n>ID}' @UI.HiddenFilter; - title @title:'{i18n>Title}'; - author @title:'{i18n>AuthorID}'; - price @title:'{i18n>Price}'; - stock @title:'{i18n>Stock}'; - descr @UI.MultiLineText; -} - - -//////////////////////////////////////////////////////////////////////////// -// -// Authors Elements -// -annotate my.Authors with { - ID @title:'{i18n>ID}' @UI.HiddenFilter; - name @title:'{i18n>AuthorName}'; -} diff --git a/packages/bookshop/app/fiori.html b/packages/bookshop/app/fiori.html deleted file mode 100644 index 2fc2a0d4..00000000 --- a/packages/bookshop/app/fiori.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - Bookshop - - - - - - - - - - \ No newline at end of file diff --git a/packages/bookshop/app/index.cds b/packages/bookshop/app/index.cds deleted file mode 100644 index 431bace1..00000000 --- a/packages/bookshop/app/index.cds +++ /dev/null @@ -1,8 +0,0 @@ -/* - This model controls what gets served to Fiori frontends... -*/ - -using from './admin/fiori-service'; -using from './browse/fiori-service'; -using from './orders/fiori-service'; -using from './common'; diff --git a/packages/bookshop/app/orders/fiori-service.cds b/packages/bookshop/app/orders/fiori-service.cds deleted file mode 100644 index a504a022..00000000 --- a/packages/bookshop/app/orders/fiori-service.cds +++ /dev/null @@ -1,118 +0,0 @@ -using AdminService from '../../srv/admin-service'; - -annotate AdminService.Books with { - price @Common.FieldControl: #ReadOnly; -} -//////////////////////////////////////////////////////////////////////////// -// -// Common -// -annotate AdminService.OrderItems with { - book @( - Common: { - Text: book.title, - FieldControl: #Mandatory - }, - ValueList.entity:'Books', - ); - amount @( - Common.FieldControl: #Mandatory - ); -} - - -@odata.draft.enabled -annotate AdminService.Orders with @( - UI: { - //////////////////////////////////////////////////////////////////////////// - // - // Lists of Orders - // - SelectionFields: [ createdAt, createdBy ], - LineItem: [ - {Value: createdBy, Label:'Customer'}, - {Value: createdAt, Label:'Date'} - ], - //////////////////////////////////////////////////////////////////////////// - // - // Order Details - // - HeaderInfo: { - TypeName: 'Order', TypeNamePlural: 'Orders', - Title: { - Label: 'Order number ', //A label is possible but it is not considered on the ObjectPage yet - Value: OrderNo - }, - Description: {Value: createdBy} - }, - Identification: [ //Is the main field group - {Value: createdBy, Label:'Customer'}, - {Value: createdAt, Label:'Date'}, - {Value: OrderNo }, - ], - HeaderFacets: [ - {$Type: 'UI.ReferenceFacet', Label: '{i18n>Created}', Target: '@UI.FieldGroup#Created'}, - {$Type: 'UI.ReferenceFacet', Label: '{i18n>Modified}', Target: '@UI.FieldGroup#Modified'}, - ], - Facets: [ - {$Type: 'UI.ReferenceFacet', Label: '{i18n>Details}', Target: '@UI.FieldGroup#Details'}, - {$Type: 'UI.ReferenceFacet', Label: '{i18n>OrderItems}', Target: 'Items/@UI.LineItem'}, - ], - FieldGroup#Details: { - Data: [ - {Value: currency_code, Label:'Currency'} - ] - }, - FieldGroup#Created: { - Data: [ - {Value: createdBy}, - {Value: createdAt}, - ] - }, - FieldGroup#Modified: { - Data: [ - {Value: modifiedBy}, - {Value: modifiedAt}, - ] - }, - }, -) { - createdAt @UI.HiddenFilter:false; - createdBy @UI.HiddenFilter:false; -}; - - - -//The enity types name is AdminService.my_bookshop_OrderItems -//The annotations below are not generated in edmx WHY? -annotate AdminService.OrderItems with @( - UI: { - HeaderInfo: { - TypeName: 'Order Item', TypeNamePlural: ' ', - Title: { - Value: book.title - }, - Description: {Value: book.descr} - }, - // There is no filterbar for items so the selctionfileds is not needed - SelectionFields: [ book_ID ], - //////////////////////////////////////////////////////////////////////////// - // - // Lists of OrderItems - // - LineItem: [ - {Value: book_ID, Label:'Book'}, - //The following entry is only used to have the assoication followed in the read event - {Value: book.price, Label:'Book Price'}, - {Value: amount, Label:'Quantity'}, - ], - Identification: [ //Is the main field group - //{Value: ID, Label:'ID'}, //A guid shouldn't be on the UI - {Value: book_ID, Label:'Book'}, - {Value: amount, Label:'Amount'}, - ], - Facets: [ - {$Type: 'UI.ReferenceFacet', Label: '{i18n>OrderItems}', Target: '@UI.Identification'}, - ], - }, -); \ No newline at end of file diff --git a/packages/bookshop/app/orders/webapp/Component.js b/packages/bookshop/app/orders/webapp/Component.js deleted file mode 100644 index e40eb3be..00000000 --- a/packages/bookshop/app/orders/webapp/Component.js +++ /dev/null @@ -1,22 +0,0 @@ -sap.ui.define(["sap/fe/AppComponent"], ac => ac.extend("orders.Component", { - metadata:{ manifest:'json' } -})) - -// sap.ui.define (["sap/ui/core/UIComponent"], ui5 => ui5.extend("bookshop.Component", { -// metadata: { manifest: "json" } -// })) -// sap.ui.define (["sap/ui/generic/app/AppComponent"], ui5 => ui5.extend("bookshop.Component", { -// metadata: { manifest: "json" } -// })) - -// jQuery.sap.declare("bookshop.Component"); -// sap.ui.getCore().loadLibrary("sap.ui.generic.app"); -// jQuery.sap.require("sap.ui.generic.app.AppComponent"); - -// sap.ui.generic.app.AppComponent.extend("bookshop.Component", { -// metadata: { -// manifest: "json" -// } -// }); - -/* eslint no-undef:0 */ \ No newline at end of file diff --git a/packages/bookshop/app/orders/webapp/i18n/i18n.properties b/packages/bookshop/app/orders/webapp/i18n/i18n.properties deleted file mode 100644 index 28b03dff..00000000 --- a/packages/bookshop/app/orders/webapp/i18n/i18n.properties +++ /dev/null @@ -1,11 +0,0 @@ -# This is the resource bundle of itelo -# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459 - -# JCI app descriptor contains lower case TITLE -appTitle=Bookshop Sample - -# JCI app descriptor contains lower case DESCRIPTION -appSubTitle=CAP Sample Application - -# JCI app descriptor contains lower case DESCRIPTION -appDescription=CDS Sample Service diff --git a/packages/bookshop/app/orders/webapp/manifest.json b/packages/bookshop/app/orders/webapp/manifest.json deleted file mode 100644 index e33eb24b..00000000 --- a/packages/bookshop/app/orders/webapp/manifest.json +++ /dev/null @@ -1,170 +0,0 @@ -{ - "_version": "1.8.0", - "sap.app": { - "id": "orders", - "type": "application", - "title": "Manage Orders", - "description": "Sample Application", - "i18n": "i18n/i18n.properties", - "dataSources": { - "AdminService": { - "uri": "/admin/", - "type": "OData", - "settings": { - "odataVersion": "4.0" - } - } - }, - "-sourceTemplate": { - "id": "ui5template.basicSAPUI5ApplicationProject", - "-id": "ui5template.smartTemplate", - "-version": "1.40.12" - } - }, - "sap.ui5": { - "dependencies": { - "libs": { - "sap.fe": {} - } - }, - "models": { - "i18n": { - "type": "sap.ui.model.resource.ResourceModel", - "uri": "i18n/i18n.properties" - }, - "": { - "dataSource": "AdminService", - "settings": { - "synchronizationMode": "None", - "operationMode": "Server", - "autoExpandSelect" : true, - "earlyRequests": true, - "groupProperties": { - "default": { - "submit": "Auto" - } - } - } - } - }, - "routing": { - "routes": [ - { - "pattern": ":?query:", - "name": "OrdersList", - "target": "OrdersList" - }, - { - "pattern": "Orders({key}):?query:", - "name": "OrdersDetails", - "target": "OrdersDetails" - }, - { - "pattern": "Orders({boo})/Items({boo2}):?query:", - "name": "OrderItemsDetails", - "target": "OrderItemsDetails" - }, - { - "pattern": "Books({key}):?query:", - "name": "BooksDetails", - "target": "BooksDetails" - } - ], - "targets": { - "OrdersList": { - "type": "Component", - "id": "OrdersList", - "name": "sap.fe.templates.ListReport", - "options": { - "settings" : { - "entitySet" : "Orders", - "navigation" : { - "Orders" : { - "detail" : { - "route" : "OrdersDetails" - } - } - } - } - } - }, - "OrdersDetails": { - "type": "Component", - "id": "OrdersDetails", - "name": "sap.fe.templates.ObjectPage", - "options": { - "settings" : { - "entitySet": "Orders", - "navigation" : { - "Items": { - "detail": { - "route": "OrderItemsDetails" - } - }, - "book": { - "detail": { - "route": "BooksDetails" - } - }, - "dummy": { - "detail": { - "route": "BooksDetails" - } - } - } - } - } - }, - "OrderItemsDetails": { - "type": "Component", - "id": "OrderItemsDetails", - "name": "sap.fe.templates.ObjectPage", - "options": { - "settings" : { - "entitySet": "OrderItems" - } - } - }, - "BooksDetails": { - "type": "Component", - "id": "BooksDetails", - "name": "sap.fe.templates.ObjectPage", - "options": { - "settings" : { - "entitySet": "Books", - "navigation": { - "author": { - "detail": { - "route": "AuthorsDetails" - } - } - } - } - } - }, - "AuthorsDetails": { - "type": "Component", - "id": "AuthorsDetails", - "name": "sap.fe.templates.ObjectPage", - "options": { - "settings" : { - "entitySet": "Authors" - } - } - } - } - }, - "contentDensities": { - "compact": true, - "cozy": true - } - }, - "sap.ui": { - "technology": "UI5", - "fullWidth": false - }, - "sap.fiori": { - "registrationIds": [], - "archeType": "transactional" - } -} \ No newline at end of file diff --git a/packages/bookshop/db/data/sap.capire.bookshop-Authors.csv b/packages/bookshop/db/data/sap.capire.bookshop-Authors.csv deleted file mode 100644 index f97bfeed..00000000 --- a/packages/bookshop/db/data/sap.capire.bookshop-Authors.csv +++ /dev/null @@ -1,5 +0,0 @@ -ID;name;dateOfBirth;placeOfBirth;dateOfDeath;placeOfDeath -101;Emily Brontë;1818-07-30;Thornton, Yorkshire;1848-12-19;Haworth, Yorkshire -107;Charlotte Brontë;1818-04-21;Thornton, Yorkshire;1855-03-31;Haworth, Yorkshire -150;Edgar Allen Poe;1809-01-19;Boston, Massachusetts;1849-10-07;Baltimore, Maryland -170;Richard Carpenter;1929-08-14;King’s Lynn, Norfolk;2012-02-26;Hertfordshire, England \ No newline at end of file diff --git a/packages/bookshop/db/data/sap.capire.bookshop-Books.csv b/packages/bookshop/db/data/sap.capire.bookshop-Books.csv deleted file mode 100644 index a767360c..00000000 --- a/packages/bookshop/db/data/sap.capire.bookshop-Books.csv +++ /dev/null @@ -1,6 +0,0 @@ -ID;title;descr;author_ID;stock;price;currency_code -201;Wuthering Heights;"Wuthering Heights, Emily Brontë's only novel, was published in 1847 under the pseudonym ""Ellis Bell"". It was written between October 1845 and June 1846. Wuthering Heights and Anne Brontë's Agnes Grey were accepted by publisher Thomas Newby before the success of their sister Charlotte's novel Jane Eyre. After Emily's death, Charlotte edited the manuscript of Wuthering Heights and arranged for the edited version to be published as a posthumous second edition in 1850.";101;12;11.11;GBP -207;Jane Eyre;"Jane Eyre /ɛər/ (originally published as Jane Eyre: An Autobiography) is a novel by English writer Charlotte Brontë, published under the pen name ""Currer Bell"", on 16 October 1847, by Smith, Elder & Co. of London. The first American edition was published the following year by Harper & Brothers of New York. Primarily a bildungsroman, Jane Eyre follows the experiences of its eponymous heroine, including her growth to adulthood and her love for Mr. Rochester, the brooding master of Thornfield Hall. The novel revolutionised prose fiction in that the focus on Jane's moral and spiritual development is told through an intimate, first-person narrative, where actions and events are coloured by a psychological intensity. The book contains elements of social criticism, with a strong sense of Christian morality at its core and is considered by many to be ahead of its time because of Jane's individualistic character and how the novel approaches the topics of class, sexuality, religion and feminism.";107;11;12.34;GBP -251;The Raven;"""The Raven"" is a narrative poem by American writer Edgar Allan Poe. First published in January 1845, the poem is often noted for its musicality, stylized language, and supernatural atmosphere. It tells of a talking raven's mysterious visit to a distraught lover, tracing the man's slow fall into madness. The lover, often identified as being a student, is lamenting the loss of his love, Lenore. Sitting on a bust of Pallas, the raven seems to further distress the protagonist with its constant repetition of the word ""Nevermore"". The poem makes use of folk, mythological, religious, and classical references.";150;333;13.13;USD -252;Eleonora;"""Eleonora"" is a short story by Edgar Allan Poe, first published in 1842 in Philadelphia in the literary annual The Gift. It is often regarded as somewhat autobiographical and has a relatively ""happy"" ending.";150;555;14;USD -271;Catweazle;Catweazle is a British fantasy television series, starring Geoffrey Bayldon in the title role, and created by Richard Carpenter for London Weekend Television. The first series, produced and directed by Quentin Lawrence, was screened in the UK on ITV in 1970. The second series, directed by David Reid and David Lane, was shown in 1971. Each series had thirteen episodes, most but not all written by Carpenter, who also published two books based on the scripts.;170;22;15;EUR \ No newline at end of file diff --git a/packages/bookshop/db/data/sap.capire.bookshop-Books_texts.csv b/packages/bookshop/db/data/sap.capire.bookshop-Books_texts.csv deleted file mode 100644 index fcd8a35e..00000000 --- a/packages/bookshop/db/data/sap.capire.bookshop-Books_texts.csv +++ /dev/null @@ -1,4 +0,0 @@ -ID;locale;title;descr -201;de;Sturmhöhe;Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman der englischen Schriftstellerin Emily Brontë (1818–1848). Der 1847 unter dem Pseudonym Ellis Bell veröffentlichte Roman wurde vom viktorianischen Publikum weitgehend abgelehnt, heute gilt er als ein Klassiker der britischen Romanliteratur des 19. Jahrhunderts. -207;de;Jane Eyre;Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography), erstmals erschienen im Jahr 1847 unter dem Pseudonym Currer Bell, ist der erste veröffentlichte Roman der britischen Autorin Charlotte Brontë und ein Klassiker der viktorianischen Romanliteratur des 19. Jahrhunderts. Der Roman erzählt in Form einer Ich-Erzählung die Lebensgeschichte von Jane Eyre (ausgesprochen /ˌdʒeɪn ˈɛə/), die nach einer schweren Kindheit eine Stelle als Gouvernante annimmt und sich in ihren Arbeitgeber verliebt, jedoch immer wieder um ihre Freiheit und Selbstbestimmung kämpfen muss. Als klein, dünn, blass, stets schlicht dunkel gekleidet und mit strengem Mittelscheitel beschrieben, gilt die Heldin des Romans Jane Eyre nicht zuletzt aufgrund der Kino- und Fernsehversionen der melodramatischen Romanvorlage als die bekannteste englische Gouvernante der Literaturgeschichte -252;de;Eleonora;“Eleonora” ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841 erstveröffentlicht. In ihr geht es um das Paradox der Treue in der Treulosigkeit. \ No newline at end of file diff --git a/packages/bookshop/db/data/sap.capire.bookshop-OrderItems.csv b/packages/bookshop/db/data/sap.capire.bookshop-OrderItems.csv deleted file mode 100644 index 25edab7a..00000000 --- a/packages/bookshop/db/data/sap.capire.bookshop-OrderItems.csv +++ /dev/null @@ -1,4 +0,0 @@ -ID;amount;parent_ID;book_ID;netAmount -58040e66-1dcd-4ffb-ab10-fdce32028b79;1;7e2f2640-6866-4dcf-8f4d-3027aa831cad;201;11.11 -64e718c9-ff99-47f1-8ca3-950c850777d4;1;7e2f2640-6866-4dcf-8f4d-3027aa831cad;271;15 -e9641166-e050-4261-bfee-d1e797e6cb7f;2;64e718c9-ff99-47f1-8ca3-950c850777d4;252;28 \ No newline at end of file diff --git a/packages/bookshop/db/data/sap.capire.bookshop-Orders.csv b/packages/bookshop/db/data/sap.capire.bookshop-Orders.csv deleted file mode 100644 index 088c1e87..00000000 --- a/packages/bookshop/db/data/sap.capire.bookshop-Orders.csv +++ /dev/null @@ -1,3 +0,0 @@ -ID;modifiedAt;createdAt;createdBy;modifiedBy;OrderNo;currency_code -7e2f2640-6866-4dcf-8f4d-3027aa831cad;;2019-01-31;john.doe@test.com;;1;EUR -64e718c9-ff99-47f1-8ca3-950c850777d4;;2019-01-30;jane.doe@test.com;;2;EUR \ No newline at end of file diff --git a/packages/bookshop/db/data/sap.common-Currencies.csv b/packages/bookshop/db/data/sap.common-Currencies.csv deleted file mode 100644 index 48f3ec32..00000000 --- a/packages/bookshop/db/data/sap.common-Currencies.csv +++ /dev/null @@ -1,7 +0,0 @@ -code;symbol;name;descr -EUR;€;Euro;European Euro -USD;$;US Dollar;United States Dollar -CAD;$;Canadian Dollar;Canadian Dollar -AUD;$;Australian Dollar;Australian Dollar -GBP;£;Pound;Great Britain Pound -ILS;₪;Shekel;Israeli New Shekel \ No newline at end of file diff --git a/packages/bookshop/db/data/sap.common-Currencies_texts.csv b/packages/bookshop/db/data/sap.common-Currencies_texts.csv deleted file mode 100644 index 4d2ead51..00000000 --- a/packages/bookshop/db/data/sap.common-Currencies_texts.csv +++ /dev/null @@ -1,13 +0,0 @@ -code;locale;name;descr -EUR;de;Euro;European Euro -USD;de;US-Dollar;United States Dollar -CAD;de;Kanadischer Dollar;Kanadischer Dollar -AUD;de;Australischer Dollar;Australischer Dollar -GBP;de;Pfund;Britische Pfund -ILS;de;Schekel;Israelische Schekel -EUR;fr;euro;de la Zone euro -USD;fr;dollar;dollar des États-Unis -CAD;fr;dollar canadien;dollar canadien -AUD;fr;dollar australien;dollar australien -GBP;fr;livre sterling;pound sterling -ILS;fr;Shekel;shekel israelien \ No newline at end of file diff --git a/packages/bookshop/db/schema.cds b/packages/bookshop/db/schema.cds deleted file mode 100644 index e0e587be..00000000 --- a/packages/bookshop/db/schema.cds +++ /dev/null @@ -1,35 +0,0 @@ -namespace sap.capire.bookshop; -using { Currency, managed, cuid } from '@sap/cds/common'; - -entity Books : managed { - key ID : Integer; - title : localized String(111); - descr : localized String(1111); - author : Association to Authors; - stock : Integer; - price : Decimal(9,2); - currency : Currency; -} - -entity Authors : managed { - key ID : Integer; - name : String(111); - dateOfBirth : Date; - dateOfDeath : Date; - placeOfBirth : String; - placeOfDeath : String; - books : Association to many Books on books.author = $self; -} - -entity Orders : cuid, managed { - OrderNo : String @title:'Order Number'; //> readable key - Items : Composition of many OrderItems on Items.parent = $self; - total : Decimal(9,2) @readonly; - currency : Currency; -} -entity OrderItems : cuid { - parent : Association to Orders; - book : Association to Books; - amount : Integer; - netAmount : Decimal(9,2); -} diff --git a/packages/bookshop/package.json b/packages/bookshop/package.json deleted file mode 100644 index 6764a1b0..00000000 --- a/packages/bookshop/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "@sap/capire-bookshop", - "version": "1.0.0", - "description": "A simple bookshop application, build in a self-contained all-in-one fashion, i.e. w/o reusing other packages.", - "license": "SAP SAMPLE CODE LICENSE", - "dependencies": { - "@sap/cds": "latest", - "express": "*" - }, - "scripts": { - "start": "cds run --in-memory?", - "watch": "cds watch" - }, - "cds": { - "requires": { - "db": { - "kind": "sql" - } - } - } -} \ No newline at end of file diff --git a/packages/bookshop/srv/admin-service.cds b/packages/bookshop/srv/admin-service.cds deleted file mode 100644 index 10c0fef1..00000000 --- a/packages/bookshop/srv/admin-service.cds +++ /dev/null @@ -1,7 +0,0 @@ -using { sap.capire.bookshop as my } from '../db/schema'; - -service AdminService @(_requires:'authenticated-user') { - entity Books as projection on my.Books; - entity Authors as projection on my.Authors; - entity Orders as select from my.Orders; -} diff --git a/packages/bookshop/srv/cat-service.cds b/packages/bookshop/srv/cat-service.cds deleted file mode 100644 index efe7b5d9..00000000 --- a/packages/bookshop/srv/cat-service.cds +++ /dev/null @@ -1,13 +0,0 @@ -using { sap.capire.bookshop as my } from '../db/schema'; - -@path:'/browse' -service CatalogService { - - @readonly entity Books as SELECT from my.Books {*, - author.name as author - } excluding { createdBy, modifiedBy }; - - @requires_: 'authenticated-user' - @insertonly entity Orders as projection on my.Orders; - -} diff --git a/packages/bookshop/srv/cat-service.js b/packages/bookshop/srv/cat-service.js deleted file mode 100644 index 8ee056a7..00000000 --- a/packages/bookshop/srv/cat-service.js +++ /dev/null @@ -1,26 +0,0 @@ -const cds = require('@sap/cds') -const { Books } = cds.entities - -/** Service implementation for CatalogService */ -module.exports = cds.service.impl(function() { - this.after ('READ', 'Books', each => each.stock > 111 && _addDiscount2(each,11)) - this.before ('CREATE', 'Orders', _reduceStock) -}) - -/** Add some discount for overstocked books */ -function _addDiscount2 (each,discount) { - each.title += ` -- ${discount}% discount!` -} - -/** Reduce stock of ordered books if available stock suffices */ -async function _reduceStock (req) { - const { Items: OrderItems } = req.data - return cds.transaction(req) .run (()=> OrderItems.map (order => - UPDATE (Books) .set ('stock -=', order.amount) - .where ('ID =', order.book_ID) .and ('stock >=', order.amount) - )) .then (all => all.forEach ((affectedRows,i) => { - if (affectedRows === 0) req.error (409, - `${OrderItems[i].amount} exceeds stock for book #${OrderItems[i].book_ID}` - ) - })) -} \ No newline at end of file diff --git a/packages/bookshop/tests/bookshop.http b/packages/bookshop/tests/bookshop.http deleted file mode 100644 index 0d50023e..00000000 --- a/packages/bookshop/tests/bookshop.http +++ /dev/null @@ -1,18 +0,0 @@ -### Service Document -GET http://localhost:4004/browse - -### Service $metadata document -GET http://localhost:4004/browse/$metadata - -### Browsing Books -GET http://localhost:4004/browse/Books? -# &$select=title,author -# &$expand=currency -# &sap-language=de - -### Browsing Authors -GET http://localhost:4004/admin/Authors? -# &$select=name,dateOfBirth,placeOfBirth -# &$expand=books($select=title;$expand=currency) -# &$filter=ID eq 101 -# &sap-language=de diff --git a/packages/bookshop/tests/orders.http b/packages/bookshop/tests/orders.http deleted file mode 100644 index a0f72d1c..00000000 --- a/packages/bookshop/tests/orders.http +++ /dev/null @@ -1,18 +0,0 @@ - -### List Books with their current stocks -GET http://localhost:4004/admin/Books?$select=ID,stock - -### List all Orders -GET http://localhost:4004/admin/Orders? -&$expand=Items - -### Submit Orders -POST http://localhost:4004/browse/Orders -Content-Type: application/json - -{ "OrderNo":"2019-09...", "Items":[ - { "book_ID":201, "amount":5 }, - { "book_ID":207, "amount":3 } -]} - -# Sending this three times should result in a 409: 5 exceeds stock for book #201 \ No newline at end of file diff --git a/packages/bookstore/db/data/sap.capire.bookstore-Authors.csv b/packages/bookstore/db/data/sap.capire.bookstore-Authors.csv deleted file mode 100644 index 8c2d2f71..00000000 --- a/packages/bookstore/db/data/sap.capire.bookstore-Authors.csv +++ /dev/null @@ -1,5 +0,0 @@ -ID;firstname;lastname;dateOfBirth;placeOfBirth;dateOfDeath;placeOfDeath -101;Emily;Brontë;1818-07-30;Thornton, Yorkshire;1848-12-19;Haworth, Yorkshire -107;Charlotte;Brontë;1818-04-21;Thornton, Yorkshire;1855-03-31;Haworth, Yorkshire -150;Edgar Allen;Poe;1809-01-19;Boston, Massachusetts;1849-10-07;Baltimore, Maryland -170;Richard;Carpenter;1929-08-14;King’s Lynn, Norfolk;2012-02-26;Hertfordshire, England \ No newline at end of file diff --git a/packages/bookstore/db/data/sap.capire.products-Categories.csv b/packages/bookstore/db/data/sap.capire.products-Categories.csv deleted file mode 100644 index 331e8ba2..00000000 --- a/packages/bookstore/db/data/sap.capire.products-Categories.csv +++ /dev/null @@ -1,11 +0,0 @@ -ID;parent_ID;name -1;;Poetry -2;;Biography -3;;Fantasy -4;;Science Fiction -5;;Romance -6;;Mystery -7;;Thriller -8;;Dystopia -9;;Tragedy -10;;Novel diff --git a/packages/bookstore/db/data/sap.capire.products-Products.csv b/packages/bookstore/db/data/sap.capire.products-Products.csv deleted file mode 100644 index ddbd0834..00000000 --- a/packages/bookstore/db/data/sap.capire.products-Products.csv +++ /dev/null @@ -1,6 +0,0 @@ -ID;title;descr;author_ID;stock;price;currency_code;category_ID -201;Wuthering Heights;"Wuthering Heights, Emily Brontë's only novel, was published in 1847 under the pseudonym ""Ellis Bell"". It was written between October 1845 and June 1846. Wuthering Heights and Anne Brontë's Agnes Grey were accepted by publisher Thomas Newby before the success of their sister Charlotte's novel Jane Eyre. After Emily's death, Charlotte edited the manuscript of Wuthering Heights and arranged for the edited version to be published as a posthumous second edition in 1850.";101;12;11.11;GBP;9 -207;Jane Eyre;"Jane Eyre /ɛər/ (originally published as Jane Eyre: An Autobiography) is a novel by English writer Charlotte Brontë, published under the pen name ""Currer Bell"", on 16 October 1847, by Smith, Elder & Co. of London. The first American edition was published the following year by Harper & Brothers of New York. Primarily a bildungsroman, Jane Eyre follows the experiences of its eponymous heroine, including her growth to adulthood and her love for Mr. Rochester, the brooding master of Thornfield Hall. The novel revolutionised prose fiction in that the focus on Jane's moral and spiritual development is told through an intimate, first-person narrative, where actions and events are coloured by a psychological intensity. The book contains elements of social criticism, with a strong sense of Christian morality at its core and is considered by many to be ahead of its time because of Jane's individualistic character and how the novel approaches the topics of class, sexuality, religion and feminism.";107;11;12.34;GBP;10 -251;The Raven;"“The Raven"" is a narrative poem by American writer Edgar Allan Poe. First published in January 1845, the poem is often noted for its musicality, stylized language, and supernatural atmosphere. It tells of a talking raven's mysterious visit to a distraught lover, tracing the man's slow fall into madness. The lover, often identified as being a student, is lamenting the loss of his love, Lenore. Sitting on a bust of Pallas, the raven seems to further distress the protagonist with its constant repetition of the word ""Nevermore"". The poem makes use of folk, mythological, religious, and classical references.";150;333;13.13;USD;1 -252;Eleonora;"""Eleonora"" is a short story by Edgar Allan Poe, first published in 1842 in Philadelphia in the literary annual The Gift. It is often regarded as somewhat autobiographical and has a relatively ""happy"" ending.";150;555;14;USD;5 -271;Catweazle;Catweazle is a British fantasy television series, starring Geoffrey Bayldon in the title role, and created by Richard Carpenter for London Weekend Television. The first series, produced and directed by Quentin Lawrence, was screened in the UK on ITV in 1970. The second series, directed by David Reid and David Lane, was shown in 1971. Each series had thirteen episodes, most but not all written by Carpenter, who also published two books based on the scripts.;170;22;15;EUR;3 \ No newline at end of file diff --git a/packages/bookstore/db/data/sap.capire.products-Products_texts.csv b/packages/bookstore/db/data/sap.capire.products-Products_texts.csv deleted file mode 100644 index fcd8a35e..00000000 --- a/packages/bookstore/db/data/sap.capire.products-Products_texts.csv +++ /dev/null @@ -1,4 +0,0 @@ -ID;locale;title;descr -201;de;Sturmhöhe;Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman der englischen Schriftstellerin Emily Brontë (1818–1848). Der 1847 unter dem Pseudonym Ellis Bell veröffentlichte Roman wurde vom viktorianischen Publikum weitgehend abgelehnt, heute gilt er als ein Klassiker der britischen Romanliteratur des 19. Jahrhunderts. -207;de;Jane Eyre;Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography), erstmals erschienen im Jahr 1847 unter dem Pseudonym Currer Bell, ist der erste veröffentlichte Roman der britischen Autorin Charlotte Brontë und ein Klassiker der viktorianischen Romanliteratur des 19. Jahrhunderts. Der Roman erzählt in Form einer Ich-Erzählung die Lebensgeschichte von Jane Eyre (ausgesprochen /ˌdʒeɪn ˈɛə/), die nach einer schweren Kindheit eine Stelle als Gouvernante annimmt und sich in ihren Arbeitgeber verliebt, jedoch immer wieder um ihre Freiheit und Selbstbestimmung kämpfen muss. Als klein, dünn, blass, stets schlicht dunkel gekleidet und mit strengem Mittelscheitel beschrieben, gilt die Heldin des Romans Jane Eyre nicht zuletzt aufgrund der Kino- und Fernsehversionen der melodramatischen Romanvorlage als die bekannteste englische Gouvernante der Literaturgeschichte -252;de;Eleonora;“Eleonora” ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841 erstveröffentlicht. In ihr geht es um das Paradox der Treue in der Treulosigkeit. \ No newline at end of file diff --git a/packages/bookstore/db/schema.cds b/packages/bookstore/db/schema.cds deleted file mode 100644 index 5f82d533..00000000 --- a/packages/bookstore/db/schema.cds +++ /dev/null @@ -1,18 +0,0 @@ -namespace sap.capire.bookstore; - -// We reuse Products, which are Books in our domain -using { sap.capire.products.Products as Books } from '@sap/capire-products'; -extend Books with { - author : Association to Authors; - rating : Decimal(2,1); -} - -// We reuse aspect Person to define Authors -using { sap.capire.contacts.Person } from '@sap/capire-contacts'; -entity Authors : Person { - key ID : UUID; - books : Association to many Books on books.author = $self; -} - -// we use enhanced currencies code lists -using from '@sap/capire-currencies'; diff --git a/packages/bookstore/package.json b/packages/bookstore/package.json deleted file mode 100644 index 0f18561b..00000000 --- a/packages/bookstore/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@sap/capire-bookstore", - "version": "1.0.0", - "description": "A variant of the bookshop application, built on top of products-service and common reuse packages.", - "repository": "https://github.com/SAP-samples/cloud-cap-samples.git", - "license": "SAP SAMPLE CODE LICENSE", - "dependencies": { - "@sap/capire-products": "^1.0.0", - "@sap/capire-reviews": "^1.0.0", - "@sap/capire-orders": "^1.0.0", - "@sap/capire-media": "^1.0.0", - "@sap/capire-users": "^1.0.0", - "@sap/capire-contacts": "^1.0.0", - "@sap/capire-currencies": "^1.0.0", - "@sap/cds": "latest", - "express": "*" - }, - "bundledDependencies": [ - "@sap/capire-products", - "@sap/capire-reviews", - "@sap/capire-orders", - "@sap/capire-media", - "@sap/capire-users", - "@sap/capire-contacts", - "@sap/capire-currencies" - ], - "files": [ - "app", "srv", "db" - ], - "scripts": { - "start": "cds run --in-memory?", - "watch": "cds watch" - }, - "cds": { - "requires": { - "db": { - "kind": "sql" - }, - "sap.capire.media.MediaServer": { - "kind": "rest" - }, - "sap.capire.reviews.ReviewsService": { - "model": "@sap/capire-reviews", - "kind": "odata" - } - } - } -} diff --git a/packages/bookstore/srv/_workarounds.cds b/packages/bookstore/srv/_workarounds.cds deleted file mode 100644 index 60cc099a..00000000 --- a/packages/bookstore/srv/_workarounds.cds +++ /dev/null @@ -1,12 +0,0 @@ -//---------------------- -// workarounds -> should be done by @cds-compiler - -annotate cds.UUID with @odata.Type: 'Edm.String'; - -using from '@sap/capire-products'; -annotate sap.capire.products.Products with { texts @odata.contained } -annotate sap.capire.products.Categories with { texts @odata.contained } - -annotate sap.capire.reviews.ReviewsService with @imported; -annotate sap.capire.reviews.Reviews with @cds.persistence.skip; -annotate sap.capire.reviews.Likes with @cds.persistence.skip; diff --git a/packages/bookstore/srv/services.cds b/packages/bookstore/srv/services.cds deleted file mode 100644 index b630ebe9..00000000 --- a/packages/bookstore/srv/services.cds +++ /dev/null @@ -1,35 +0,0 @@ -namespace sap.capire.bookstore; - -// Service for all users to browse books -using { sap.capire.products } from '../db/schema'; - -service CatalogService @(path:'browse'){ - - @readonly entity Books as select from products.Products { *, - author.firstname ||' '|| author.lastname as author : String, - category.name as genre, - } excluding { createdBy, modifiedBy }; - - @readonly entity Genres as projection on products.Categories; - -} - -// Reuse AdminService from @sap/capire-products... -using { sap.capire.products.AdminService } from '@sap/capire-products'; -using { sap.capire.bookstore as my } from '../db/schema'; - -extend service AdminService with @(impl:'srv/services.js') { - entity Authors as projection on my.Authors; -} - -// Adding reviews via @sap/capire-reviews service -using { sap.capire.reviews.ReviewsService as external } from '@sap/capire-reviews'; -extend service CatalogService with { - @readonly entity Reviews as projection on external.Reviews; -} - - -// Adding images via @sap/capire-media service -using from '@sap/capire-media'; -// using from '@sap/capire-orders'; -// using from '@sap/capire-users'; diff --git a/packages/bookstore/srv/services.js b/packages/bookstore/srv/services.js deleted file mode 100644 index 3b6430aa..00000000 --- a/packages/bookstore/srv/services.js +++ /dev/null @@ -1,38 +0,0 @@ -const cds = require('@sap/cds') -module.exports['sap.capire.bookstore.CatalogService'] = cds.service.impl (async (srv) => { - - const ReviewsService = await cds.connect.to ('sap.capire.reviews.ReviewsService') - const { Reviews } = ReviewsService.entities - const { Books } = srv.entities - - // delegate requests to reviews service - srv.on('READ', 'Reviews', async (req) => { - const { SELECT } = cds.ql(req) - const results = await SELECT.from (Reviews) - - // TODO: Should actually be using .where of fluent query API - if (req.query.SELECT.where) { - return results.filter (row => row.subject === req.query.SELECT.where[2].val) - } - - return results - }) - - // react on event messages from reviews service - ReviewsService.on ('reviewed', (msg) => { - console.debug ('> received message:', msg.event, msg.data) - const {subject,rating} = msg.data - const tx = cds.transaction(msg) - return tx.run (UPDATE(Books).set({rating}) .where ({ID:subject})) //.then (console.log) - }) - -}) - - -// FIXME: pls remove this... -process.env.destinations = JSON.stringify([{ - name: 'reviewsDest', - url: 'http://localhost:4005/reviews', - username: 'dummy', - password: 'dummy' -}]) diff --git a/packages/bookstore/tests/books.cds b/packages/bookstore/tests/books.cds deleted file mode 100644 index 4c1309d9..00000000 --- a/packages/bookstore/tests/books.cds +++ /dev/null @@ -1,7 +0,0 @@ -using { sap.capire.products as my } from '../db/schema'; - -service BooksService { - entity Books as SELECT from my.Products; -} - -annotate cds.UUID with @odata.Type: 'Edm.String'; diff --git a/packages/bookstore/tests/localized-data.test.js b/packages/bookstore/tests/localized-data.test.js deleted file mode 100644 index acf35d44..00000000 --- a/packages/bookstore/tests/localized-data.test.js +++ /dev/null @@ -1,190 +0,0 @@ -const cds = require ('@sap/cds') - -describe('Localized data on db level', ()=>{ - - let db, Books - - it ('should deploy the db schema to sqlite in-memory', async()=>{ - db = await cds.deploy (__dirname+'/books') .to ('sqlite::memory:') - expect (db.model) .toBeDefined() - Books = db.entities('sap.capire.products').Products - expect (Books) .toBeDefined() - }) - - it ('should list all books with default language', async ()=>{ - const books = await SELECT.from (Books, b=>b.title) - expect (books) .toMatchObject([ - { title: 'Wuthering Heights' }, - { title: 'Jane Eyre' }, - { title: 'The Raven' }, - { title: 'Eleonora' }, - { title: 'Catweazle' } - ]) - }) - - - it ('should read translated texts from Books_texts', async ()=>{ - const texts = await SELECT ('locale','title').from (Books+'_texts') - expect (texts) .toMatchObject ([ - { locale: 'de', title: 'Sturmhöhe' }, - { locale: 'de', title: 'Jane Eyre' }, - { locale: 'de', title: 'Eleonora' } - ]) - }) - - it ('should read translated texts from Books.texts', async ()=>{ - const book = await SELECT.one.from (Books, b=>{ - b.ID, b.title, b.texts(t=> { - t.locale, t.title - }) - }) .where ({title:'Wuthering Heights'}) - expect (book) .toMatchObject ({ - title: 'Wuthering Heights', texts:[ - {locale:'de',title:'Sturmhöhe'} - ] - }) - }) - - it ('should insert books with translated texts', async ()=>{ - const n = await INSERT.into (Books) .entries ({ ID:444, title:'A New Book', texts:[ - {locale:'de', title:'Ein Neues Buch'}, - {locale:'fr', title:'Un Nouveau Livre'}, - ]}) - expect(n).toBe(3) - }) - - it ('should delete books w/ cascaded delete to texts', async()=>{ - const n = await DELETE.from(Books) .where ({ID:444}) - expect(n).toBe(3) - }) - -}) - - -describe('Localized data on service level', ()=>{ - - let srv, Books - - it ('should serve BooksService', async()=>{ - srv = await cds.serve('BooksService').from(__dirname+'/books') - expect (srv.model) .toBeDefined() - Books = srv.entities.Books - expect (Books) .toBeDefined() - }) - - it ('should list all books with default language', async ()=>{ - const books = await srv.read (Books, b=>b.title) - expect (books) .toMatchObject([ - { title: 'Wuthering Heights' }, - { title: 'Jane Eyre' }, - { title: 'The Raven' }, - { title: 'Eleonora' }, - { title: 'Catweazle' } - ]) - }) - - it ('should read Books with translated texts', async ()=>{ - const book = await srv.run ( - SELECT.from (Books, b=>{ b.ID, b.title, b.texts(t=> { - t.locale, t.title - })}) .where ({title:'Wuthering Heights'}) - ) - expect (book) .toMatchObject ([{ - title: 'Wuthering Heights', texts:[ - {locale:'de',title:'Sturmhöhe'} - ] - }]) - }) - - it ('should do the same with convenient method', async ()=>{ - const book = await srv.read (Books, b=>{ b.ID, b.title, b.texts(t=> { - t.locale, t.title - })}) .where ({title:'Wuthering Heights'}) - expect (book) .toMatchObject ([{ - title: 'Wuthering Heights', texts:[ - {locale:'de',title:'Sturmhöhe'} - ] - }]) - }) - - it ('should read single Book with translated texts', async ()=>{ - const book = await srv.run ( - SELECT.one.from (Books, b=>{ b.ID, b.title, b.texts(t=> { - t.locale, t.title - })}) .where ({title:'Wuthering Heights'}) - ) - expect (book) .toMatchObject ({ - title: 'Wuthering Heights', texts:[ - {locale:'de',title:'Sturmhöhe'} - ] - }) - }) - - it ('should insert books with translated texts', async ()=>{ - const book = { ID:444, title:'A New Book', texts:[ - {locale:'de', title:'Ein Neues Buch'}, - {locale:'fr', title:'Un Nouveau Livre'}, - ]} - const response = await srv.create (Books) .entries (book) - expect(response).toMatchObject(book) - }) - - it ('should delete books w/ cascaded delete to texts', async()=>{ - await srv.delete('Books') .where ({ID:444}) - }) -}) - - -describe('Localized data on OData level', () => { - - const app = require('express')() - const srv = require('supertest')(app) - - it ('should serve BooksService', async ()=>{ - await cds.serve('BooksService').from(__dirname+'/books') .in (app) - }) - - it('should list all books with default language', async () => { - const books = await srv.get('/books/Books/201/title') - expect(books.body).toMatchObject({'value': 'Wuthering Heights'}) - }) - - it('should read books with translated texts', async () => { - const books = await srv.get('/books/Books/201/title'). set('Accept-Language', 'de') - expect(books.body).toMatchObject({value: 'Sturmhöhe'}) - }) - - it('should expand translated texts in Book', async () => { - const books = await srv. get('/books/Books/201?$select=title&$expand=texts($select=locale,title)') - expect(books.body).toMatchObject({ - title: 'Wuthering Heights', - texts: [ - { locale: 'de', title: 'Sturmhöhe', }, - ], - }) - }) - - const book = { - title: 'New Book', descr: 'Lorem Ipsum', - texts: [ - { locale: 'de', title: 'Neues Buch', descr: 'Dolor sit amet' }, - { locale: 'fr', title: 'Nouveau Livre', descr: 'consetetur sadipscing elitr' } - ], - } - - it('should insert books with translated texts', async () => { - const {body} = await srv.post('/books/Books').send(book) - expect(body).toMatchObject(book) - book.ID = body.ID - }) - - it ('should read the newly created book', async()=>{ - const {body} = await srv.get('/books/Books/'+book.ID+'?$expand=texts').send(book) - expect(body).toMatchObject(book) - }) - - it ('should delete books w/ cascaded delete to texts', async()=>{ - await srv.delete('/books/Books/'+book.ID) - .expect(204) - }) -}) diff --git a/packages/common-contacts/db/code-lists.cds b/packages/common-contacts/db/code-lists.cds deleted file mode 100644 index 4da5c872..00000000 --- a/packages/common-contacts/db/code-lists.cds +++ /dev/null @@ -1,37 +0,0 @@ -using { sap.capire.contacts.PostalAddress } from './schema'; -using { sap } from '@sap/cds/common'; -namespace sap.capire.contacts; - -/** - * The Code Lists below are designed as optional extensions to - * the base schema. Switch them on by adding an Association to - * one of the code list entities in your models or by: - * annotate sap.common.Countries with @cds.persistence.skip:false; - */ - -entity Countries as select from sap.common.Countries; -extend sap.common.Countries { - regions : Composition of many Regions on regions._parent = $self.code; -} -entity Regions : sap.common.CodeList { - key code : String(5); // ISO 3166-2 alpha5 codes, e.g. DE-BW - children : Composition of many Regions on children._parent = $self.code; - cities : Composition of many Cities on cities.region = $self; - _parent : String(11); -} -entity Cities : sap.common.CodeList { - key code : String(11); - region : Association to Regions; - districts : Composition of many Districts on districts.city = $self; -} -entity Districts : sap.common.CodeList { - key code : String(11); - city : Association to Cities; -} - -annotate PostalAddress with { - district @ref: sap.capire.contacts.Districts; - city @ref: sap.capire.contacts.Cities; - region @ref: sap.capire.contacts.Regions; - country @ref: sap.capire.contacts.Countries; -} diff --git a/packages/common-contacts/db/data/sap.capire.contacts-Countries.csv b/packages/common-contacts/db/data/sap.capire.contacts-Countries.csv deleted file mode 100644 index 6614e27a..00000000 --- a/packages/common-contacts/db/data/sap.capire.contacts-Countries.csv +++ /dev/null @@ -1,12 +0,0 @@ -code;name;descr -AU;Australia;Commonwealth of Australia -CA;Canada;Canada -CN;China;People's Republic of China (PRC) -FR;France;French Republic -DE;Germany;Federal Republic of Germany -IN;India;Republic of India -IL;Israel;State of Israel -MM;Myanmar;Republic of the Union of Myanmar -GB;United Kingdom;United Kingdom of Great Britain and Northern Ireland -US;United States;United States of America (USA) -EU;European Union;European Union \ No newline at end of file diff --git a/packages/common-contacts/db/data/sap.capire.contacts-Countries_texts.csv b/packages/common-contacts/db/data/sap.capire.contacts-Countries_texts.csv deleted file mode 100644 index 7d078c58..00000000 --- a/packages/common-contacts/db/data/sap.capire.contacts-Countries_texts.csv +++ /dev/null @@ -1,12 +0,0 @@ -code;locale;name;descr -AU;de;Australien;Commonwealth Australien -CA;de;Kanada;Canada -CN;de;China;Volksrepublik China -FR;de;Frankreich;Republik Frankreich -DE;de;Deutschland;Bundesrepublik Deutschland -IN;de;Indien;Republik Indien -IL;de;Israel;Staat Israel -MM;de;Myanmar;Republik der Union Myanmar -GB;de;Vereinigtes Königreich;Vereinigtes Königreich Großbritannien und Nordirland -US;de;Vereinigte Staaten;Vereinigte Staaten von Amerika -EU;de;Europäische Union;Europäische Union \ No newline at end of file diff --git a/packages/common-contacts/db/schema.cds b/packages/common-contacts/db/schema.cds deleted file mode 100644 index c9a7410f..00000000 --- a/packages/common-contacts/db/schema.cds +++ /dev/null @@ -1,58 +0,0 @@ -namespace sap.capire.contacts; - - -//-------------------------------------------------------------------------- -// Aspects - - - aspect Organization { - orgname : String(111); - } - - aspect Person { - firstname : String(111); - lastname : String(111); - prefix : String(11); - suffix : String(11); - middle : String(11); - dateOfBirth : Date; placeOfBirth : String; - dateOfDeath : Date; placeOfDeath : String; - } - - aspect PostalAddress { - street : String(222) @multiline; - postCode : String(11); - district : String(111); - city : String(111); - region : String(111); - country : String(111); - } - - aspect ContactOptions { - email : String @JSON:[{ kind:String, address: EmailAddress }]; - phone : String @JSON:[{ kind:String, number: PhoneNumber }]; - // phone : array of { kind:String; number: PhoneNumber }; - // addresses : Composition of many PostalAddress; - } - - type EmailAddress : String; - type PhoneNumber : String; - - - -//-------------------------------------------------------------------------- -// Entities - - @cds.persistence.skip:'if-unused' - entity Contacts : Person, Organization, ContactOptions { - key ID : UUID; - isOrg : Boolean; - addresses : Composition of many PostalAddresses on addresses.contact = $self; - } - - @cds.persistence.skip:'if-unused' - entity PostalAddresses : PostalAddress { - contact : Association to Contacts; - kind : String; - key ID : UUID; - } diff --git a/packages/common-contacts/index.cds b/packages/common-contacts/index.cds deleted file mode 100644 index 0a1d479d..00000000 --- a/packages/common-contacts/index.cds +++ /dev/null @@ -1,2 +0,0 @@ -using from './db/code-lists'; -using from './db/schema'; diff --git a/packages/common-contacts/package.json b/packages/common-contacts/package.json deleted file mode 100644 index 4221f4ab..00000000 --- a/packages/common-contacts/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "@sap/capire-contacts", - "version": "1.0.0", - "description": "A reuse package providing common domain models and services for contacts-related data.", - "repository": "https://github.com/SAP-samples/cloud-cap-samples.git", - "license": "SAP SAMPLE CODE LICENSE", - "dependencies": { - "@sap/cds": "latest" - } -} \ No newline at end of file diff --git a/packages/common-contacts/readme.md b/packages/common-contacts/readme.md deleted file mode 100644 index 77ea0ed2..00000000 --- a/packages/common-contacts/readme.md +++ /dev/null @@ -1,67 +0,0 @@ -# Common Contacts Sample - -This sample provides a reuse package with common domain models and services for contacts-related data. - -## Usage - - -#### Import to your project - - npm install @sap/capire-contacts - -> e.g. see: [bookstore](../bookstore/package.json) - -#### Reusing aspects - -Define own entities derived from the pre-defined aspects as in [_bookstore_](../bookstore/db/schema.cds): - -```swift -using { sap.capire.contacts.Person } from '@sap/capire-contacts'; -entity Authors : contacts.Person { ... } -``` - -> **Note:** All entities in this package are annotated with _`@cds.persistence.skip`:'if-unused'_, so they will be ignored if not referred to from other entities in your models. - - -#### Reusing entities - -Reuse the entities as in this example from [_users-service_](../users-service/srv/services.cds): -```swift -using { sap.capire.contacts.Contacts } from '@sap/capire-contacts'; -service UsersService @(requires:'authenticated-user') { - entity MyProfile as select from Contacts where ID=$user; - ... -} -``` - - -#### Reusing code lists - -Reuse the code lists as in [_./tests/index.cds_](./tests/index.cds): - -```swift -service Sue { ... - // expose Countries to activate provided code lists - @readonly entity Countries as projection on sap.capire.contacts.Countries; -} -``` - - - -#### Reuse code list service - -```js -const { intercept } = require ('@sap/capire-contacts/srv/code-lists') -``` - - - -## Content - - - -## Concepts - -* [Reuse of packages](https://cap.cloud.sap/docs/get-started/projects#reuse) -* Code Lists, `@sap/cds/common` and `@cds.persistence.skip`: 'if-unused' -* Using `aspects` vs `entities` diff --git a/packages/common-contacts/srv/code-lists.js b/packages/common-contacts/srv/code-lists.js deleted file mode 100644 index aac662b8..00000000 --- a/packages/common-contacts/srv/code-lists.js +++ /dev/null @@ -1,70 +0,0 @@ -const cds = require ('@sap/cds') -const READ='READ', WRITE = ['CREATE','UPDATE'] - -const intercept = exports.intercept = cds.service.impl (async (srv) => { - - for (let each in srv.entities) { - - // intercept JSON-encoded elements - const jsons = await jsonsIn (srv.entities[each].elements) - if (jsons) { - srv.before (WRITE, each, ({data:row})=>{ - for (let e of jsons) if (row[e]) row[e] = JSON.stringify (row[e]) - }) - srv.after (READ, each, (row)=>{ - for (let e of jsons) if (row[e]) row[e] = JSON.parse (row[e]) - }) - } - - // intercept references - const refs = await refsIn (srv.entities[each].elements, srv.model) - if (refs) srv.after (READ, each, (rows, req)=>{ - for (let row of rows) { - for (let {element,codelist} of refs) { - const entry = codelist [row[element]] - if (entry) { - const localized = entry.texts [req.user.locale || intercept.locale] - row[element] = localized ? localized.name : entry.name - } - } - } - }) - - } - -}) - - -function jsonsIn (elements) { - const jsons=[]; for (let e in elements) { - if (elements[e]['@JSON']) jsons.push(e) - } - return jsons.length && jsons -} - -async function refsIn (elements, model) { - const refs=[]; for (let e in elements) { - const $ref = elements[e]['@ref'] - if ($ref) { - const d = model.definitions [$ref['=']] - refs.push({ - element:e, - codelist: CodeLists[d.name] || (CodeLists[d.name] = await load(d)) - }) - } - } - return refs.length && refs -} - -const load = exports.load = async (codelist) => { - const all = {} - const [entries,texts] = await Promise.all ([ - SELECT.from (codelist), - SELECT.from (codelist.elements.texts.target) - ]) - for (let {code,name,descr} of entries) all[code] = {name,descr} - for (let {code,locale,name,descr} of texts) (all[code].texts || (all[code].texts={})) [locale] = {name,descr} - return all -} - -const CodeLists = {} diff --git a/packages/common-contacts/tests/code-lists.test.js b/packages/common-contacts/tests/code-lists.test.js deleted file mode 100644 index ee367abf..00000000 --- a/packages/common-contacts/tests/code-lists.test.js +++ /dev/null @@ -1,68 +0,0 @@ -const {load,intercept} = require ('../srv/code-lists') -const cds = require ('@sap/cds') - -// patch-enhance cds.ql -const select = SELECT.from('.').__proto__.__proto__, query = select.__proto__ -query.then = function (r,e) { return db.run(this) .then (r,e || ((e)=>{throw e})) } - -let db, Countries, Australia = { - name: 'Australia', descr: 'Commonwealth of Australia', texts: { - de: { name: 'Australien', descr: 'Commonwealth Australien' } - } -} - -describe ('code list tests', ()=>{ - - it ('should deploy the db schema to sqlite in-memory', async()=>{ - db = await cds.deploy (__dirname) .to ('sqlite::memory:', {silent:true,primary:true}) - Countries = db.model.entities ['sap.common.Countries'] - expect (Countries) .toBeDefined() - }) - - it ('should read Countries', async()=>{ - const countries = await SELECT ('code','name') .from (Countries) - expect (countries) .toContainEqual ({ code: 'AU', name: 'Australia' }) - }) - - it ('should read Countries_texts', async()=>{ - const countries = await SELECT ('locale','code','name') .from ('sap.common.Countries_texts') - expect (countries) .toContainEqual ({ locale: 'de', code: 'AU', name: 'Australien' }) - }) - - it ('should read code lists with translated texts', async()=>{ - const {AU} = await load (Countries) - expect (AU) .toEqual (Australia) - }) - - cds.env.singletenant = true - - it ('should serve services with localized data', async()=>{ - const { Sue:sue } = await cds.serve (__dirname) - const { Foos } = sue.entities - await sue.create (Foos) .entries ({country:'Avalon'}) - await sue.create (Foos) .entries ({country:'AU'}) - expect (await sue.read('Foos')) .toEqual ([ { ID: 1, country: 'Avalon' }, { ID: 2, country: 'AU' } ]) - }) - - it ('should resolve countries', async()=>{ - const sue = await cds.connect.to ('Sue') - await intercept (sue) - expect (await sue.read('Foos')) .toEqual ([ { ID: 1, country: 'Avalon' }, { ID: 2, country: 'Australia' } ]) - intercept.locale = 'de' - expect (await sue.read('Foos')) .toEqual ([ { ID: 1, country: 'Avalon' }, { ID: 2, country: 'Australien' } ]) - console.log (await sue.read('Foos')) - }) - - it ('should read countries with expand to translated texts', async()=>{ - const countries = await cds.read (Countries, c=>{ - c.name, c.texts (t => { - t.locale, t.name - }) - }) - console.log (countries) - }) - - it ('should disconnect from db', ()=> db.disconnect()) - //> FIXME: that should not be required! - -}) diff --git a/packages/common-contacts/tests/index.cds b/packages/common-contacts/tests/index.cds deleted file mode 100644 index 96adbe01..00000000 --- a/packages/common-contacts/tests/index.cds +++ /dev/null @@ -1,11 +0,0 @@ -using { sap } from '..'; - -entity Foo { - key ID : Integer; - country : String @ref: sap.capire.contacts.Countries; -} -service Sue { - entity Foos as projection on Foo; - // expose Countries to activate provided code lists - @readonly entity Countries as projection on sap.capire.contacts.Countries; -} diff --git a/packages/common-currencies/data/sap.common-Currencies.csv b/packages/common-currencies/data/sap.common-Currencies.csv deleted file mode 100644 index 63372602..00000000 --- a/packages/common-currencies/data/sap.common-Currencies.csv +++ /dev/null @@ -1,12 +0,0 @@ -code;symbol;name;descr;numcode;minor;exponent -EUR;€;Euro;European Euro;978;Cent;2 -USD;$;US Dollar;United States Dollar;840;Cent;2 -CAD;$;Canadian Dollar;Canadian Dollar;124;Cent;2 -AUD;$;Australian Dollar;Canadian Dollar;036;Cent;2 -GBP;£;British Pound;Great Britain Pound;826;Penny;2 -ILS;₪;Shekel;Israeli New Shekel;376;Agorat;2 -INR;₹;Rupee;Indian Rupee;356;Paise;2 -QAR;﷼;Riyal;Katar Riyal;356;Dirham;2 -SAR;﷼;Riyal;Saudi Riyal;682;Halala;2 -JPY;¥;Yen;Japanese Yen;392;Sen;2 -CNY;¥;Yuan;Chinese Yuan Renminbi;156;Jiao;1 \ No newline at end of file diff --git a/packages/common-currencies/data/sap.common-Currencies_texts.csv b/packages/common-currencies/data/sap.common-Currencies_texts.csv deleted file mode 100644 index 4d2ead51..00000000 --- a/packages/common-currencies/data/sap.common-Currencies_texts.csv +++ /dev/null @@ -1,13 +0,0 @@ -code;locale;name;descr -EUR;de;Euro;European Euro -USD;de;US-Dollar;United States Dollar -CAD;de;Kanadischer Dollar;Kanadischer Dollar -AUD;de;Australischer Dollar;Australischer Dollar -GBP;de;Pfund;Britische Pfund -ILS;de;Schekel;Israelische Schekel -EUR;fr;euro;de la Zone euro -USD;fr;dollar;dollar des États-Unis -CAD;fr;dollar canadien;dollar canadien -AUD;fr;dollar australien;dollar australien -GBP;fr;livre sterling;pound sterling -ILS;fr;Shekel;shekel israelien \ No newline at end of file diff --git a/packages/common-currencies/index.cds b/packages/common-currencies/index.cds deleted file mode 100644 index 82da4228..00000000 --- a/packages/common-currencies/index.cds +++ /dev/null @@ -1,17 +0,0 @@ -namespace sap.capire.currencies; -using { sap.common.Currencies } from '@sap/cds/common'; - -extend Currencies with { - // Currencies.code = ISO 4217 alphabetic three-letter code - // with the first two letters being equal to ISO 3166 alphabetic country codes - numcode : Integer; - exponent : Integer; //> e.g. 2 --> 1 Dollar = 10^2 Cent - minor : String; //> e.g. 'Cent' - // country : String; //> country or region -} - - -// see also -// [1] https://www.iso.org/iso-4217-currency-codes.html -// [2] https://www.currency-iso.org/en/home/tables/table-a1.html -// [3] https://www.ibm.com/support/knowledgecenter/en/SSZLC2_7.0.0/com.ibm.commerce.payments.developer.doc/refs/rpylerl2mst97.htm \ No newline at end of file diff --git a/packages/common-currencies/package.json b/packages/common-currencies/package.json deleted file mode 100644 index 68be970e..00000000 --- a/packages/common-currencies/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "@sap/capire-currencies", - "version": "1.0.0", - "description": "A reuse package providing common domain models and services for currencies-related data.", - "repository": "https://github.com/SAP-samples/cloud-cap-samples.git", - "license": "SAP SAMPLE CODE LICENSE", - "dependencies": { - "@sap/cds": "latest" - } -} diff --git a/packages/media-server/db/data-model.cds b/packages/media-server/db/data-model.cds deleted file mode 100644 index 2ad6c28e..00000000 --- a/packages/media-server/db/data-model.cds +++ /dev/null @@ -1,13 +0,0 @@ -namespace sap.capire.media; - -entity Media { - - key id:Integer; - @Core.MediaType: mediaType - content : LargeBinary ; - - @Core.IsMediaType: true - mediaType : String; - fileName : String; - applicationName:String; -} \ No newline at end of file diff --git a/packages/media-server/index.cds b/packages/media-server/index.cds deleted file mode 100644 index 9ac07e86..00000000 --- a/packages/media-server/index.cds +++ /dev/null @@ -1,2 +0,0 @@ -using from './db/data-model'; -using from './srv/media-service'; diff --git a/packages/media-server/package.json b/packages/media-server/package.json deleted file mode 100644 index c144037d..00000000 --- a/packages/media-server/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@sap/capire-media", - "version": "1.0.0", - "description": "A generic platform service to manage and serve media content on behalf of other services and apps.", - "repository": "https://github.com/SAP-samples/cloud-cap-samples.git", - "license": "SAP SAMPLE CODE LICENSE", - "dependencies": { - "@sap/cds": "latest", - "express": "*", - "lokijs": "^1.5.6" - }, - "files": [ - "db", - "srv", - "index.cds" - ], - "cds": { - "requires": { - "db": { - "kind": "sql" - } - } - } -} diff --git a/packages/media-server/srv/media-service.cds b/packages/media-server/srv/media-service.cds deleted file mode 100644 index 09441897..00000000 --- a/packages/media-server/srv/media-service.cds +++ /dev/null @@ -1,8 +0,0 @@ -using { sap.capire.media as db } from '../db/data-model'; -namespace sap.capire.media; - -service MediaServer { - entity Media as projection on db.Media ; -} - - \ No newline at end of file diff --git a/packages/media-server/srv/media-service.js b/packages/media-server/srv/media-service.js deleted file mode 100644 index f70d3b90..00000000 --- a/packages/media-server/srv/media-service.js +++ /dev/null @@ -1,68 +0,0 @@ -const loki = require('lokijs') -const db = new loki('DB') -const mediaDB = db.addCollection('Media') -const { Readable, PassThrough } = require('stream') - -module.exports = srv => { - srv.before('CREATE', 'Media', req => { - const obj = mediaDB.insert({ media: '' }) - req.data.id = obj.$loki - }) - - srv.on('UPDATE', 'Media', (req, next) => { - const url = req._.req.path - if (url.includes('content')) { - const id = req.data.id - const obj = mediaDB.get(id) - if (!obj) { - req.reject(404, 'No record found for the ID') - return - } - const stream = new PassThrough() - const chunks = [] - stream.on('data', chunk => { - chunks.push(chunk) - }) - stream.on('end', () => { - obj.media = Buffer.concat(chunks).toString('base64') - mediaDB.update(obj) - }) - req.data.content.pipe(stream) - } else return next() - }) - - srv.on('READ', 'Media', (req, next) => { - const url = req._.req.path - if (url.includes('content')) { - const id = req.data.id - const mediaObj = mediaDB.get(id) - if (!mediaObj) { - req.reject(404, 'Media not found for the ID') - return - } - const decodedMedia = new Buffer( - mediaObj.media.split(';base64,').pop(), - 'base64' - ) - return _formatResult(decodedMedia) - } else return next() //> delegate to next/default handlers - }) - - srv.on('DELETE', 'Media', (req, next) => { - const id = req.data.id - mediaDB - .chain() - .find({ $loki: id }) - .remove() - return next() //> delegate to next/default handlers - }) - - function _formatResult (decodedMedia) { - const readable = new Readable() - const result = new Array() - readable.push(decodedMedia) - readable.push(null) - result.push({ value: readable }) - return result - } -} diff --git a/packages/officesupplies/.eslintrc b/packages/officesupplies/.eslintrc new file mode 100644 index 00000000..639d13a0 --- /dev/null +++ b/packages/officesupplies/.eslintrc @@ -0,0 +1,24 @@ +{ + "extends": "eslint:recommended", + "env": { + "node": true, + "es6": true, + "jest": true + }, + "parserOptions": { + "ecmaVersion": 2017 + }, + "globals": { + "SELECT": true, + "INSERT": true, + "UPDATE": true, + "DELETE": true, + "CREATE": true, + "DROP": true, + "cds": true + }, + "rules": { + "no-console": "off", + "require-atomic-updates": "off" + } +} diff --git a/packages/officesupplies/.gitignore b/packages/officesupplies/.gitignore new file mode 100644 index 00000000..fccac7b6 --- /dev/null +++ b/packages/officesupplies/.gitignore @@ -0,0 +1,23 @@ +# CAP officesupplies +_out +*.db +connection.properties +default-*.json +gen/ +node_modules/ +package-lock.json +target/ + +# Web IDE, App Studio +.che/ +.gen/ + +# MTA +*_mta_build_tmp +*.mtar +mta_archives/ + +# Other +.DS_Store +*.orig +*.log diff --git a/packages/officesupplies/.vscode/cds.js b/packages/officesupplies/.vscode/cds.js new file mode 100644 index 00000000..a9e6d6fc --- /dev/null +++ b/packages/officesupplies/.vscode/cds.js @@ -0,0 +1,4 @@ +// used in launch.json to refer to an installed cds via an absolute path + +const cds = require('@sap/cds'); +cds.exec(); diff --git a/packages/officesupplies/.vscode/launch.json b/packages/officesupplies/.vscode/launch.json new file mode 100644 index 00000000..f4c88965 --- /dev/null +++ b/packages/officesupplies/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "cds run", + "type": "node", + "request": "launch", + "program": "${workspaceFolder}/.vscode/cds", + "args": [ "run", "--with-mocks", "--in-memory?" ], + "skipFiles": [ "/**" ], + "internalConsoleOptions": "openOnSessionStart", + "console": "internalConsole", + "autoAttachChildProcesses": true + } + ] +} diff --git a/packages/officesupplies/.vscode/settings.json b/packages/officesupplies/.vscode/settings.json new file mode 100644 index 00000000..9fefa082 --- /dev/null +++ b/packages/officesupplies/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.exclude": { + "**/.gitignore": true, + "**/.git": true, + "**/.vscode": true + } +} diff --git a/packages/officesupplies/.vscode/tasks.json b/packages/officesupplies/.vscode/tasks.json new file mode 100644 index 00000000..c8762fab --- /dev/null +++ b/packages/officesupplies/.vscode/tasks.json @@ -0,0 +1,23 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "type": "shell", + "label": "cds watch", + "command": ["cds", "watch"], + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + }, + { + "type": "shell", + "label": "cds run", + "command": ["cds", "run", "--with-mocks", "--in-memory?"], + "problemMatcher": [] + } + ] +} diff --git a/packages/officesupplies/README.md b/packages/officesupplies/README.md new file mode 100644 index 00000000..be0b6d2f --- /dev/null +++ b/packages/officesupplies/README.md @@ -0,0 +1,25 @@ +# Getting Started + +Welcome to your new project. + +It contains these folders and files, following our recommended project layout: + +File / Folder | Purpose +---------|---------- +`app/` | content for UI frontends go here +`db/` | your domain models and data go here +`srv/` | your service models and code go here +`package.json` | project metadata and configuration +`readme.md` | this getting started guide + + +## Next Steps... + +- Open a new terminal and run `cds watch` +- ( in VSCode simply choose _**Terminal** > Run Task > cds watch_ ) +- Start adding content, e.g. a [db/schema.cds](db/schema.cds), ... + + +## Learn more... + +Learn more at https://cap.cloud.sap/docs/get-started/ diff --git a/packages/officesupplies/app/products/.npmrc b/packages/officesupplies/app/products/.npmrc new file mode 100644 index 00000000..493198f8 --- /dev/null +++ b/packages/officesupplies/app/products/.npmrc @@ -0,0 +1,4 @@ +@sap:registry=https://npm.sap.com +@ui5:registry=https://registry.npmjs.org +save = true +save-exact = true diff --git a/packages/officesupplies/app/products/README.md b/packages/officesupplies/app/products/README.md new file mode 100644 index 00000000..ee316928 --- /dev/null +++ b/packages/officesupplies/app/products/README.md @@ -0,0 +1,21 @@ +# products + +This is a my new Fiori elements app + +## Starting the generated app + +- This app has been generated using the SAP UX - App Generator, as part of the SAP UX Tools Suite. In order to launch the generated app, simply run the following from the generated app root folder: + +``` + npm start +``` + +- Is it also possible to run the application using mock data that reflects the OData Service URL supplied during application generation. In order to run the application with Mock Data, run the following from the generated app root folder: + +``` + npm run start-mock +``` + +### Pre-requisites: + +1. Active NodeJS LTS (Long Term Support) version and associated supported NPM version. (See https://nodejs.org) diff --git a/packages/officesupplies/app/products/package.json b/packages/officesupplies/app/products/package.json new file mode 100644 index 00000000..c95e0931 --- /dev/null +++ b/packages/officesupplies/app/products/package.json @@ -0,0 +1,33 @@ +{ + "name": "products", + "version": "0.0.1", + "private": true, + "sapux": true, + "description": "This is a my new Fiori elements app", + "keywords": [ + "ui5", + "openui5", + "sapui5" + ], + "main": "webapp/index.html", + "scripts": { + "start": "npm run start-app-router", + "start-app-router": "npm run build && run-script-os", + "start-app-router:default": "destinations='[{\"name\":\"odata\",\"url\":\"http://localhost:4004\",\"strictSSL\":false}]' node node_modules/@sap/approuter/approuter.js", + "start-app-router:windows": "set destinations=[{\"name\":\"odata\",\"url\":\"http://localhost:4004\",\"strictSSL\":false}] && node node_modules/@sap/approuter/approuter.js", + "build": "rimraf dist && ui5 build -a --include-task=generateManifestBundle generateCachebusterInfo" + }, + "remarkConfig": { + "plugins": [ + "remark-preset-lint-consistent" + ] + }, + "dependencies": { + "@sap/approuter": "6.5.1", + "@ui5/cli": "1.8.0" + }, + "devDependencies": { + "run-script-os": "1.0.7", + "rimraf": "3.0.0" + } +} diff --git a/packages/officesupplies/app/products/ui5.yaml b/packages/officesupplies/app/products/ui5.yaml new file mode 100644 index 00000000..80a20289 --- /dev/null +++ b/packages/officesupplies/app/products/ui5.yaml @@ -0,0 +1,4 @@ +specVersion: '1.0' +metadata: + name: products +type: application diff --git a/packages/officesupplies/app/products/webapp/Component.js b/packages/officesupplies/app/products/webapp/Component.js new file mode 100644 index 00000000..f7afb607 --- /dev/null +++ b/packages/officesupplies/app/products/webapp/Component.js @@ -0,0 +1,10 @@ +/* global hasher */ +sap.ui.define(['sap/fe/AppComponent'], function(AppComponent) { + 'use strict'; + + return AppComponent.extend('sap.uxfe.demo.products.Component', { + metadata: { + manifest: 'json' + } + }); +}); diff --git a/packages/officesupplies/app/products/webapp/WEB-INF/web.xml b/packages/officesupplies/app/products/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..d0c20200 --- /dev/null +++ b/packages/officesupplies/app/products/webapp/WEB-INF/web.xml @@ -0,0 +1,118 @@ + + + + OData v4 + + + + + + + ResourceServlet + ResourceServlet + com.sap.ui5.resource.ResourceServlet + + + ResourceServlet + /resources/* + + + ResourceServlet + /test-resources/* + + + + + com.sap.ui5.resource.ACCEPTED_ORIGINS + * + + + + + + + com.sap.ui5.resource.DEV_MODE + true + + + + + + + + + + CacheControlFilter + CacheControlFilter + com.sap.ui5.resource.CacheControlFilter + + + CacheControlFilter + *.html + + + CacheControlFilter + *.js + + + CacheControlFilter + *.css + + + CacheControlFilter + *.json + + + CacheControlFilter + *.xml + + + CacheControlFilter + *.gif + + + CacheControlFilter + *.png + + + CacheControlFilter + *.jpg + + + CacheControlFilter + *.properties + + + CacheControlFilter + *.tmpl + + + + + + + + + SimpleProxyServlet + com.sap.ui5.proxy.SimpleProxyServlet + + + SimpleProxyServlet + /proxy/* + + + + + + + + + test.html + + + + \ No newline at end of file diff --git a/packages/officesupplies/app/products/webapp/i18n/i18n.properties b/packages/officesupplies/app/products/webapp/i18n/i18n.properties new file mode 100644 index 00000000..0d689684 --- /dev/null +++ b/packages/officesupplies/app/products/webapp/i18n/i18n.properties @@ -0,0 +1,9 @@ +# This is the resource bundle for products + +#Texts for manifest.json + +#XTIT: Application name +appTitle=Products + +#YDES: Application description +appDescription=This is a my new Fiori elements app diff --git a/packages/officesupplies/app/products/webapp/index.html b/packages/officesupplies/app/products/webapp/index.html new file mode 100644 index 00000000..b7baa672 --- /dev/null +++ b/packages/officesupplies/app/products/webapp/index.html @@ -0,0 +1,38 @@ + + + + + + + {{appTitle}} + + + + + + + + + diff --git a/packages/officesupplies/app/products/webapp/localService/metadata.xml b/packages/officesupplies/app/products/webapp/localService/metadata.xml new file mode 100644 index 00000000..8c94f07d --- /dev/null +++ b/packages/officesupplies/app/products/webapp/localService/metadata.xml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/officesupplies/app/products/webapp/manifest.json b/packages/officesupplies/app/products/webapp/manifest.json new file mode 100644 index 00000000..c8d0b948 --- /dev/null +++ b/packages/officesupplies/app/products/webapp/manifest.json @@ -0,0 +1,133 @@ +{ + "_version": "1.15.0", + "sap.app": { + "id": "sap.uxfe.demo.products", + "type": "application", + "i18n": "i18n/i18n.properties", + "applicationVersion": { + "version": "1.0" + }, + "title": "{{appTitle}}", + "description": "{{appDescription}}", + "ach": "CA-UI5-FE", + "dataSources": { + "mainService": { + "uri": "/catalog/", + "type": "OData", + "settings": { + "odataVersion": "4.0" + } + } + }, + "offline": false, + "resources": "resources.json", + "sourceTemplate": { + "id": "ui5template.fiorielements.v4.lrop", + "version": "1.0.0" + } + }, + "sap.ui": { + "technology": "UI5", + "icons": { + "icon": "", + "favIcon": "", + "phone": "", + "phone@2": "", + "tablet": "", + "tablet@2": "" + }, + "deviceTypes": { + "desktop": true, + "tablet": true, + "phone": true + } + }, + "sap.ui5": { + "resources": { + "js": [], + "css": [] + }, + "dependencies": { + "minUI5Version": "1.71.0", + "libs": { + "sap.fe": {} + } + }, + "models": { + "i18n": { + "type": "sap.ui.model.resource.ResourceModel", + "uri": "i18n/i18n.properties" + }, + "": { + "dataSource": "mainService", + "settings": { + "synchronizationMode": "None", + "operationMode": "Server", + "autoExpandSelect": true, + "earlyRequests": true + } + } + }, + "routing": { + "routes": [ + { + "pattern": "", + "name": "ProductsList", + "target": "ProductsList" + }, + { + "pattern": "Products({key})", + "name": "ProductsObjectPage", + "target": "ProductsObjectPage" + } + ], + "targets": { + "ProductsList": { + "type": "Component", + "id": "ProductsList", + "name": "sap.fe.templates.ListReport", + "options": { + "settings": { + "entitySet": "Products", + "variantManagement": "Page", + "navigation": { + "Products": { + "detail": { + "route": "ProductsObjectPage" + } + } + } + } + } + }, + "ProductsObjectPage": { + "type": "Component", + "id": "ProductsObjectPage", + "name": "sap.fe.templates.ObjectPage", + "options": { + "settings": { + "entitySet": "Products" + } + } + } + } + }, + "contentDensities": { + "compact": true, + "cozy": true + } + }, + "sap.platform.abap": { + "_version": "1.1.0", + "uri": "" + }, + "sap.platform.hcp": { + "_version": "1.1.0", + "uri": "" + }, + "sap.fiori": { + "_version": "1.1.0", + "registrationIds": [], + "archeType": "transactional" + } +} diff --git a/packages/officesupplies/app/products/xs-app.json b/packages/officesupplies/app/products/xs-app.json new file mode 100644 index 00000000..43d328f1 --- /dev/null +++ b/packages/officesupplies/app/products/xs-app.json @@ -0,0 +1,16 @@ +{ + "welcomeFile": "/index.html", + "authenticationMethod": "none", + "routes": [ + { + "source": "^/catalog/(.*)$", + "target": "/catalog/$1", + "destination": "odata", + "csrfProtection": false + }, + { + "source": "^(.*)", + "localDir": "webapp" + } + ] +} diff --git a/packages/officesupplies/app/suppliers/.npmrc b/packages/officesupplies/app/suppliers/.npmrc new file mode 100644 index 00000000..493198f8 --- /dev/null +++ b/packages/officesupplies/app/suppliers/.npmrc @@ -0,0 +1,4 @@ +@sap:registry=https://npm.sap.com +@ui5:registry=https://registry.npmjs.org +save = true +save-exact = true diff --git a/packages/officesupplies/app/suppliers/README.md b/packages/officesupplies/app/suppliers/README.md new file mode 100644 index 00000000..b8b4e8cc --- /dev/null +++ b/packages/officesupplies/app/suppliers/README.md @@ -0,0 +1,21 @@ +# suppliers + +This is a my new Fiori elements app + +## Starting the generated app + +- This app has been generated using the SAP UX - App Generator, as part of the SAP UX Tools Suite. In order to launch the generated app, simply run the following from the generated app root folder: + +``` + npm start +``` + +- Is it also possible to run the application using mock data that reflects the OData Service URL supplied during application generation. In order to run the application with Mock Data, run the following from the generated app root folder: + +``` + npm run start-mock +``` + +### Pre-requisites: + +1. Active NodeJS LTS (Long Term Support) version and associated supported NPM version. (See https://nodejs.org) diff --git a/packages/officesupplies/app/suppliers/package.json b/packages/officesupplies/app/suppliers/package.json new file mode 100644 index 00000000..ea4de3e1 --- /dev/null +++ b/packages/officesupplies/app/suppliers/package.json @@ -0,0 +1,33 @@ +{ + "name": "suppliers", + "version": "0.0.1", + "private": true, + "sapux": true, + "description": "This is a my new Fiori elements app", + "keywords": [ + "ui5", + "openui5", + "sapui5" + ], + "main": "webapp/index.html", + "scripts": { + "start": "npm run start-app-router", + "start-app-router": "npm run build && run-script-os", + "start-app-router:default": "destinations='[{\"name\":\"odata\",\"url\":\"http://localhost:4004\",\"strictSSL\":false}]' node node_modules/@sap/approuter/approuter.js", + "start-app-router:windows": "set destinations=[{\"name\":\"odata\",\"url\":\"http://localhost:4004\",\"strictSSL\":false}] && node node_modules/@sap/approuter/approuter.js", + "build": "rimraf dist && ui5 build -a --include-task=generateManifestBundle generateCachebusterInfo" + }, + "remarkConfig": { + "plugins": [ + "remark-preset-lint-consistent" + ] + }, + "dependencies": { + "@sap/approuter": "6.5.1", + "@ui5/cli": "1.8.0" + }, + "devDependencies": { + "run-script-os": "1.0.7", + "rimraf": "3.0.0" + } +} diff --git a/packages/officesupplies/app/suppliers/ui5.yaml b/packages/officesupplies/app/suppliers/ui5.yaml new file mode 100644 index 00000000..29a42240 --- /dev/null +++ b/packages/officesupplies/app/suppliers/ui5.yaml @@ -0,0 +1,4 @@ +specVersion: '1.0' +metadata: + name: suppliers +type: application diff --git a/packages/officesupplies/app/suppliers/webapp/Component.js b/packages/officesupplies/app/suppliers/webapp/Component.js new file mode 100644 index 00000000..aaf2ec93 --- /dev/null +++ b/packages/officesupplies/app/suppliers/webapp/Component.js @@ -0,0 +1,10 @@ +/* global hasher */ +sap.ui.define(['sap/fe/AppComponent'], function(AppComponent) { + 'use strict'; + + return AppComponent.extend('supplier.suppliers.Component', { + metadata: { + manifest: 'json' + } + }); +}); diff --git a/packages/officesupplies/app/suppliers/webapp/WEB-INF/web.xml b/packages/officesupplies/app/suppliers/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..d0c20200 --- /dev/null +++ b/packages/officesupplies/app/suppliers/webapp/WEB-INF/web.xml @@ -0,0 +1,118 @@ + + + + OData v4 + + + + + + + ResourceServlet + ResourceServlet + com.sap.ui5.resource.ResourceServlet + + + ResourceServlet + /resources/* + + + ResourceServlet + /test-resources/* + + + + + com.sap.ui5.resource.ACCEPTED_ORIGINS + * + + + + + + + com.sap.ui5.resource.DEV_MODE + true + + + + + + + + + + CacheControlFilter + CacheControlFilter + com.sap.ui5.resource.CacheControlFilter + + + CacheControlFilter + *.html + + + CacheControlFilter + *.js + + + CacheControlFilter + *.css + + + CacheControlFilter + *.json + + + CacheControlFilter + *.xml + + + CacheControlFilter + *.gif + + + CacheControlFilter + *.png + + + CacheControlFilter + *.jpg + + + CacheControlFilter + *.properties + + + CacheControlFilter + *.tmpl + + + + + + + + + SimpleProxyServlet + com.sap.ui5.proxy.SimpleProxyServlet + + + SimpleProxyServlet + /proxy/* + + + + + + + + + test.html + + + + \ No newline at end of file diff --git a/packages/officesupplies/app/suppliers/webapp/i18n/i18n.properties b/packages/officesupplies/app/suppliers/webapp/i18n/i18n.properties new file mode 100644 index 00000000..43a7889e --- /dev/null +++ b/packages/officesupplies/app/suppliers/webapp/i18n/i18n.properties @@ -0,0 +1,9 @@ +# This is the resource bundle for suppliers + +#Texts for manifest.json + +#XTIT: Application name +appTitle=suppliers + +#YDES: Application description +appDescription=This is a my new Fiori elements app diff --git a/packages/officesupplies/app/suppliers/webapp/index.html b/packages/officesupplies/app/suppliers/webapp/index.html new file mode 100644 index 00000000..4bc3c3b9 --- /dev/null +++ b/packages/officesupplies/app/suppliers/webapp/index.html @@ -0,0 +1,38 @@ + + + + + + + {{appTitle}} + + + + + + + + + diff --git a/packages/officesupplies/app/suppliers/webapp/localService/metadata.xml b/packages/officesupplies/app/suppliers/webapp/localService/metadata.xml new file mode 100644 index 00000000..5b641301 --- /dev/null +++ b/packages/officesupplies/app/suppliers/webapp/localService/metadata.xml @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + identifier + title + availability + price + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/officesupplies/app/suppliers/webapp/manifest.json b/packages/officesupplies/app/suppliers/webapp/manifest.json new file mode 100644 index 00000000..b25ea1f7 --- /dev/null +++ b/packages/officesupplies/app/suppliers/webapp/manifest.json @@ -0,0 +1,155 @@ +{ + "_version": "1.15.0", + "sap.app": { + "id": "supplier.suppliers", + "type": "application", + "i18n": "i18n/i18n.properties", + "applicationVersion": { + "version": "1.0" + }, + "title": "{{appTitle}}", + "description": "{{appDescription}}", + "ach": "CA-UI5-FE", + "dataSources": { + "mainService": { + "uri": "/catalog/", + "type": "OData", + "settings": { + "odataVersion": "4.0" + } + } + }, + "offline": false, + "resources": "resources.json", + "sourceTemplate": { + "id": "ui5template.fiorielements.v4.lrop", + "version": "1.0.0" + } + }, + "sap.ui": { + "technology": "UI5", + "icons": { + "icon": "", + "favIcon": "", + "phone": "", + "phone@2": "", + "tablet": "", + "tablet@2": "" + }, + "deviceTypes": { + "desktop": true, + "tablet": true, + "phone": true + } + }, + "sap.ui5": { + "resources": { + "js": [], + "css": [] + }, + "dependencies": { + "minUI5Version": "1.71.0", + "libs": { + "sap.fe": {} + } + }, + "models": { + "i18n": { + "type": "sap.ui.model.resource.ResourceModel", + "uri": "i18n/i18n.properties" + }, + "": { + "dataSource": "mainService", + "settings": { + "synchronizationMode": "None", + "operationMode": "Server", + "autoExpandSelect": true, + "earlyRequests": true + } + } + }, + "routing": { + "routes": [ + { + "pattern": "", + "name": "SuppliersList", + "target": "SuppliersList" + }, + { + "pattern": "Suppliers({key})", + "name": "SuppliersObjectPage", + "target": "SuppliersObjectPage" + }, + { + "pattern": "Suppliers({key})/texts({key2})", + "name": "Currencies_textsObjectPage", + "target": "Currencies_textsObjectPage" + } + ], + "targets": { + "SuppliersList": { + "type": "Component", + "id": "SuppliersList", + "name": "sap.fe.templates.ListReport", + "options": { + "settings": { + "entitySet": "Suppliers", + "variantManagement": "Page", + "navigation": { + "Suppliers": { + "detail": { + "route": "SuppliersObjectPage" + } + } + } + } + } + }, + "SuppliersObjectPage": { + "type": "Component", + "id": "SuppliersObjectPage", + "name": "sap.fe.templates.ObjectPage", + "options": { + "settings": { + "entitySet": "Suppliers", + "navigation": { + "texts": { + "detail": { + "route": "Currencies_textsObjectPage" + } + } + } + } + } + }, + "Currencies_textsObjectPage": { + "type": "Component", + "id": "Currencies_textsObjectPage", + "name": "sap.fe.templates.ObjectPage", + "options": { + "settings": { + "entitySet": "Currencies_texts" + } + } + } + } + }, + "contentDensities": { + "compact": true, + "cozy": true + } + }, + "sap.platform.abap": { + "_version": "1.1.0", + "uri": "" + }, + "sap.platform.hcp": { + "_version": "1.1.0", + "uri": "" + }, + "sap.fiori": { + "_version": "1.1.0", + "registrationIds": [], + "archeType": "transactional" + } +} diff --git a/packages/officesupplies/app/suppliers/xs-app.json b/packages/officesupplies/app/suppliers/xs-app.json new file mode 100644 index 00000000..43d328f1 --- /dev/null +++ b/packages/officesupplies/app/suppliers/xs-app.json @@ -0,0 +1,16 @@ +{ + "welcomeFile": "/index.html", + "authenticationMethod": "none", + "routes": [ + { + "source": "^/catalog/(.*)$", + "target": "/catalog/$1", + "destination": "odata", + "csrfProtection": false + }, + { + "source": "^(.*)", + "localDir": "webapp" + } + ] +} diff --git a/packages/officesupplies/db/csv/sap.capire.officesupplies-Products.csv b/packages/officesupplies/db/csv/sap.capire.officesupplies-Products.csv new file mode 100644 index 00000000..76e679a5 --- /dev/null +++ b/packages/officesupplies/db/csv/sap.capire.officesupplies-Products.csv @@ -0,0 +1,7 @@ +ID,IDENTIFIER,TITLE,DESCRIPTION,AVAILABILITY,STORAGE_CAPACITY,CRITICALITY,PRICE,CURRENCY_CODE,SUPPLIER_ID,IMAGE_URL +844ede5c-071e-34ed-907f-f99cb3a4693d,MC-CM-1003,Tea- / Coffee-Mug,Robust high-quality ceramic mug for every-day use in two unobstrusive colours.,153,200,0,2.65,USD,8b001df1-dab2-39a2-8b1a-89b6b445e237,https://github.wdf.sap.corp/raw/FE-SAMPLES/fe-samples-tutorial-playground01/master/images/mug.png +64d40922-ea0d-30f9-9b83-eb4448ee4c2e,MC-CH-1000,Coat Hangers,"Set of high-quality hangers with coated surface, trouser bar - anti slip. Super slim design - space saving - The hooks can be rotated through 360 degree rotation, practical for various room situations. Material: ABS (plastic); Colour: turquoise.",10,200,3,2.6,USD,12726eec-165c-3713-a674-3d2fc4f5127f,https://github.wdf.sap.corp/raw/FE-SAMPLES/fe-samples-tutorial-playground01/master/images/hanger1.png +a6756d40-792e-34c9-8b2e-df3acb0c54b4,MC-CH-1001,Coat Hangers,"Set of high-quality hangers with coated surface, trouser bar - anti slip. Super slim design - space saving - The hooks can be rotated through 360 degree rotation, practical for various room situations. Material: ABS (plastic); Colour: assorted (2 of each pink, grey, blue green, black).",34,200,2,21.73,USD,12726eec-165c-3713-a674-3d2fc4f5127f,https://github.wdf.sap.corp/raw/FE-SAMPLES/fe-samples-tutorial-playground01/master/images/hanger2.png +37f028f0-1dd5-30ae-9cdd-a7f543e4d61d,MC-CH-1002,Wooden Coat Hangers - Pack of 5,"Pack of 5 quality wooden hangers with trouser bar. Slim design for space saving - The hooks can be rotated through 360 degree rotation, practical for various room situations. Material: ABS (plastic); Colour: assorted (2 of each pink, grey, blue green, black).",5,200,2,6.4,USD,8b001df1-dab2-39a2-8b1a-89b6b445e237,https://github.wdf.sap.corp/raw/FE-SAMPLES/fe-samples-tutorial-playground01/master/images/hanger3.png +a376e380-00e8-3d90-ba9f-c332c2df0f28,MC-CH-1003,Designer Coat Hooks - Pack of 3,Pack of 3 designer coat hook. Heavy-duty stainless steel hooks in a stylish shape.,6,200,1,6.49,USD,8b001df1-dab2-39a2-8b1a-89b6b445e237,https://github.wdf.sap.corp/raw/FE-SAMPLES/fe-samples-tutorial-playground01/master/images/hanger4.png +fc16c43d-bb4e-30db-8b7e-98b3fdc7f0b9,MC-CH-1004,Vacuum Wall Hook - Pack of 6,"Big suction cup with diameter of 70mm, can load more than 10kg; bright contemporary colour; Principle of work: Atmospheric pressure, safely and easy to install and tear off, no need to drill a hole or add glue, without any damage to the surface; can be used on a variety of surfaces, including paint, glasses, wood, ceramic tile, gypsum, and any other smooth surface.",17,200,0,5.76,USD,12726eec-165c-3713-a674-3d2fc4f5127f,https://github.wdf.sap.corp/raw/FE-SAMPLES/fe-samples-tutorial-playground01/master/images/hanger4.png \ No newline at end of file diff --git a/packages/officesupplies/db/csv/sap.capire.officesupplies-Suppliers.csv b/packages/officesupplies/db/csv/sap.capire.officesupplies-Suppliers.csv new file mode 100644 index 00000000..54871cbc --- /dev/null +++ b/packages/officesupplies/db/csv/sap.capire.officesupplies-Suppliers.csv @@ -0,0 +1,16 @@ +ID,IDENTIFIER,NAME,COUNTRY,POSTCODE,CITY,STREET,BUILDING,PHONE +12726eec-165c-3713-a674-3d2fc4f5127f,OFFIPOR,OffiPOR,PR,Guaynabo,PR 00968,City View Plaza,301,+1 787-38515864 +9655e5b6-bd8c-31ee-b94a-0651449721a0,POLIRADO,POLirado,PL,Warszawa,02-675,Ul. Woloska,5,+48 883 77522087 +f1fd8dd5-3156-3469-b4f1-a03ff5041080,REGULCUST,Regular Custom Ltd,GB,Knutsford,WA16 6DW,King Street,25,+44 1565 47759991 +bb2fa1e5-5c3a-3d26-b5c1-ed53f3e08622,OFFICEGURU,Office-Guru AG,DE,Siegen,57078,Birlenbacher Str.,19-21,+49 271 7722547 +b91f077f-2086-3517-8244-d3b50835651b,MEINRESSORT,Mein Ressort GmbH,CH,Regensdorf,8105,Althardstrasse,80,+41 44 84008483 +8b001df1-dab2-39a2-8b1a-89b6b445e237,OFFICELINE,Office Line Prag,CZ,Praha,140 00,Vyskocilova,1481/4,+420 776 9487923 +3c7e6cbb-ea0f-35d2-a2ce-c85057a57916,DEPOT4ALL,Depot-4All,DE,Freiberg a. N.,71691,Grundelbachstrasse,10,+49 7141 2463585 +41b46958-5ad7-30b6-9884-b547c1e26b7e,ITELOFFICE,ITeL-Office,DE,Dresden,01187,Chemnitzer Strasse,48,+49 351 31915489 +7c5a5e3a-6dfa-35d3-8bf4-0cadbddb761a,FAMOUSUS,FamousUS,US,Houston,TX 77098,2601 Westheimer Road,Suite C250,+1 713-12001085 +36de419f-0a4c-3a5a-b285-188979ce13ec,CHINACHAIN,ChinaChain,CN,Guangzhou,510613,No. 233 Tien He Road North,6402-6403,+86 20 86454650 +41b922ad-35d9-352d-80c7-ee63ba1c007c,FAMOUSUS1,FamousUS (LV),US,Las Vegas,NV 89118,W Sunset Rd,3620,+1 702-486454400 +b4b3188c-fa27-3467-a38a-f36ede8acc18,FAMOUSUS2,FamousUS (SF),US,South San Francisco,CA 94080,Forbes Blvd,401,+1 650-486454500 +b5f1b294-a102-38e1-88c5-9b4d9ff0dd33,FAMOUSUS3,FamousUS (NY),US,New York,NY 10128,3rd Ave,1588,+1 212-486454600 +391da904-9acd-334b-885e-4b4da38f3c6e,FAMOUSUS4,FamousUS (ORL),US,Orlando,FL 32806,W Sturtevant St,47,+1 407-486454700 +1f6aed3b-bac0-39e5-ba5b-c091b0d18f40,FAMOUSUS5,FamousUS (NSH),US,Nashville,TN 37211,Space Park S Dr,486-810,+1 615-486454800 \ No newline at end of file diff --git a/packages/officesupplies/db/csv/sap.common-Currencies.csv b/packages/officesupplies/db/csv/sap.common-Currencies.csv new file mode 100644 index 00000000..eedc0cc3 --- /dev/null +++ b/packages/officesupplies/db/csv/sap.common-Currencies.csv @@ -0,0 +1,5 @@ +"SYMBOL";"DESCR";"NAME";"CODE" +"€";"Euro";"Euro";"EUR" +"£";"British Pound";"British Pound";"GBP" +"₹";"Indian Rupee";"Indian Rupee";"INR" +"$";"US Dollar";"US Dollar";"USD" \ No newline at end of file diff --git a/packages/officesupplies/db/schema.cds b/packages/officesupplies/db/schema.cds new file mode 100644 index 00000000..0af9983b --- /dev/null +++ b/packages/officesupplies/db/schema.cds @@ -0,0 +1,30 @@ +namespace sap.capire.officesupplies; +using { Currency } from '@sap/cds/common'; + +entity Products { + @Common.Label : 'UUID' + key ID : UUID; + identifier : String @Common.Label : 'ID'; + title : localized String @( Common.Label : 'Name' ); + description : localized String; + availability : Integer; + storage_capacity: Integer; + criticality : Integer; + price : Decimal(9,2); + currency : Currency; + supplier : Association to Suppliers; + image_url : String; +} + +entity Suppliers { + key ID : UUID; + identifier: String; + name : String; + phone : String; + building : String; + street : String @multiline; + postCode : String; + city : String; + country : String; + products : Composition of many Products on products.supplier = $self; +} \ No newline at end of file diff --git a/packages/officesupplies/i18n/i18n.properties b/packages/officesupplies/i18n/i18n.properties new file mode 100644 index 00000000..bbd9bad0 --- /dev/null +++ b/packages/officesupplies/i18n/i18n.properties @@ -0,0 +1,19 @@ +Cat.ProductID=ProductID +Cat.ProductStock=In Stock +Cat.ProductPrice=Price +Cat.ProductTitle=Title +Cat.ProductDescr=Description +Cat.ProductImage=Image +Cat.SuppliersIdentifier=Name +Cat.SuppliersPostCode=City +Cat.SuppliersPhone=Phone + +Cat.HeaderFacetDetails=Details +Cat.HeaderFacetSupplier=Supplier +Cat.HeaderPrice=Price + +Cat.FacetProductInformation=Product Information +Cat.FacetSectionDescription=Description + +Cat.TypeName=Product +Cat.TypeNamePlural=Products \ No newline at end of file diff --git a/packages/officesupplies/images/box.png b/packages/officesupplies/images/box.png new file mode 100644 index 0000000000000000000000000000000000000000..4556b5afbc0e7b91a9a0bdda76092034a4df4f4b GIT binary patch literal 12307 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 H^uzxGRmm>V literal 0 HcmV?d00001 diff --git a/packages/officesupplies/images/eraser.png b/packages/officesupplies/images/eraser.png new file mode 100644 index 0000000000000000000000000000000000000000..1ddee188f193b7d0e91ab1aa3b96008eb779b4ba GIT binary patch literal 42706 zcmeFYWn7e9)IK_NDX4&;q=JBS4;`X}v@mojDJ|WDfbvKRNVkZ{&@EjL;Lu1n2m(?= z4GnYl_`L5q=i~W$e!u?*9hm#xd#}CL+Sj_)TAL4A8cH`w?~_6xkee#XPhUVF_~2)J zQer~z4f0D0H~1iNRW@{oKzLcO|8RWrWxXH}W{ApDd0n5G?fJlrOwT~}%OMe=R4I8I zAJUKqA9!F~92FCK6?OL<8to@}|IECYcJeG=Fq$>JXM&!n;ms|D@;Nnz?IbwwIF-+H z8aj0D;MIOHlvv%Uv)U!+> z_tGu*mR3|9N1q@N5TYVzMFu{C4MT9jM~=J}_Df-6?5=_d<#E8rFf#}CyZiVA;D5Q$ z9PBT4x2UimH~-I||D%Zi;}QSAIvTVU1d!p3&m7$e#Rzy56MEezK60)6U$uB1G<+f6 zs^NOQwvxMU>LnznWKz`HaE1UPR$*ZQi~n%mgJ9({x_k^RxJ&Q&yt0tH?{zFLWVq6S z0l)-3l$KVr^6RxgoKWi`Fbd*szwN%oG%M5i=ooegggsE2l>-v|g(E@)9cKcJ=C zE162O`uPbTvh=1b6>Q+>D$>*`zWtn)W;$A_zJa^1rWOa{GggxThP4FcazzxfPR@L= zoJq5awh4#Gt(>c9LFCL^+NisH;-l|n*t{D^Q4xeC{q{4)f!vtJg`BHjeQQr5CRwxR zMiNDS9$vi#(b9&;;0 zD5H1>Li?`+CpD0)i_A#7So2_$7b955mKs7Q2knkx@eAv7XX1Rd)YPS}A90q`d`8IJFeU^3pVSuc)ksN{xvwV$*I zBCX;Jt5H53YVj~@L+8V7JP0t2hp{q$>WoLI*Y_62TaJHzH5;T`J)@JEpBUpLi_*aV z`^rG{{?quOnq?g)jmlc?K6U9zK8MjP($E2GLk%A`TsbCl7huVa+>aL4_BsSczCuz7 zR+V%yv>E?iN3k0wPnVl+PeJ zu|U5YURyuY*4|AfT8oPl=Us2+F|fZV%KA0~d#3%36A~=*YXb)|fAMg*tTBkPQ}2FoR9W_f)1IADLA)$0;cbTPiI)wW$)aN+H8cz(gMTev~bU zo(og)Zx7mw^EyIysQH>p%_<;}BQda1(}JMR`r2RCWo6J~Iv;eog*w8?RV>M>cNbR< zMM(u2j{f?>39l2Y=a~tmF*^Fv!t*yeFbJes6F9Se;i8@1+2GOf-ML#Q?|_vb)mL^r zf>A@{n1BxqJ0VKh41|bTZfWXWiFHTAWP%W+keoWKrS9{5WBcA<_G*YSUCr}~R2K{> zGfzmgeoX_}h@r`!`4Z~DW#sGt6uP~caT4?pxz1_i{FPf32AnQW7tF1W2w?a7={0ED zY%UK|y44-=xf}x?VR!uQTylns(`Z*hiCm*s7a_|d~7X!-wrs|%= zoXR1>xwkk2OmKo3S->HrQ`4=Eu@8wj78uv1F6M~nSS5jM2mlh)AaC76?r43u`Lgdk zA}PH*4>D|wT|_rv0bS#6k``fAxom2}2jIBAx8u^7@c`y~%VKE=2kX zP;!B~Zh7}HQ0{bZZwcyi4=u!w5?C&?wjo4Bbf!D$o4vV+Fn%!OLm-Rg<`qf9pZ7_5 zWBxL_Z!Rr5oPim!rcg<28r`0fS9RJ>>bVE8qrgs3T?rlVpCbXMo7j-1+~`Cp~(TNGA+l(;1g>L~tJaHfG`nF93>~qw|%^ zz%t*-F%o>4?)2Z67Q-$U;w^8CA&^jozmmN_dh!LGGOXPsk(Jy@C*lXM2uCVZdYS}NXT7;rqs7z|MZA9lKi(}cGy1e zVVIL+;q&7FM32h5`)sMr1?eVYw(M2=lnuSY(w}F*k z!{(oA%=GrcZc{n(^|_^&fDJzY+Zh$rs~-GPQmg@h;mtM#LWqrQF^H4L-#&9)N1PAv zjHe*%GNWtnK>Q-X6X)`l&z@{f)`wvK%5K^Osso>_AA{)opS$aN3e`6RC8)YjculX6 zLaO7ia}_}wXN^YO9CkL4MMOMBTt*roXOIR#S+34Ne?+1P&AAcL^Rm&B2r`_GRYPR7 ziVdfcgOfJZO6}3VQ~*Hj{V4lovLJF4!0N-)o1+wnhI*6RO1CtWr40(*h9;(AkPUV0 zsZvRVBJ}MXeV$CP-z%~!+1d(Z2ciLXkmE4s!VA^+J=`Mh*dLFjH+k{9WfqJw#f}=7 zA)Pe3{b*0~8%G3;8g;gYJy3@K^YHl{d|c>L7h=f9l|xu1 z_YN*(-V0AMZq=Qd@8TiK1Jfqs^1QO4;}JC3TKuIgPEJqRZS1E0sBfRMmX*39Q&}lN ze5+{WnOtXEs}$Q)$n-(d|$Itw4|s*Sxx+#1bxa)LblKLIW(c6(dZ>P1x-2Nnocb^S!xIEcj0MU@x?pi zn<0MG?dNwF9i7!n?tMxBY~S%#Y7yVW=nV|vQ4{}G;O4#^{=17l=NM>yVDv&Qo8hE7HK7vhR`p@#>jAQLM)Igh zru0HPE^;c}M{d$Y>R((hf{BLksuC3*^r!;du_d|WQT>;%1XVB4>mJ_LE zH{3G71=tz9))}HfuaKhZ!*Be${13@>b0Ru+-(#_HL_f*8eo$ze2sdPUg`ljKu9~0U zAloSMt-u$oy3RScH>~~cTw2KS#~I-v$Gt*DQ&lQ?aq+O`Qh!IVHF~WGzw)va1b(e( zJVH#&mWP4-_f(pJ7O=HsGG6a@%`BVkh#ablAc_UR^~rDc{B#{n3K6#^znjy*8k0BEnfmg1<`k9Vv$0SEEOd z3|1be`tg@PMt+qqqxVshC3&e()qDoaG6R`>54q^3JG)N|akT)2Ct%oUvxx!+;OVq?g zATlk20saM-dQIkcA;!|E5f6h0r?QMNA?R9MLTrs=!w3uQSjPx1Ef=p@Ax zAl7Ej%4HN8pFkUAYTDY~;BV+C)Pncf(3~MV)`zy1{Q8|tcAJpW3Vf}!v6LMyJGSx zsU(gR&I(m78DOx%&*wc~R|wYR5z=bt3F8Iq7{YnjJW12)cY1MlC1wxF5CdVN#XIGk_iVNrExSOz{X!_sTKzz@k9bgyylo;JA6;FR1s4K@yi#$P-5(39dx6@f z5aCX-XW(E$OsVgvQ5Qv?o!LcX_zGeI&s<9ya^_t4-X@49SefDz0+)qI(BCmJY${2~ zc0d?x{Wx(LAje7LPXMa`S3x`iFT`wRL20si6%XP$CxsPnfBSJf#>QG)N3C@eIGyWu z@KSWw&sXv-r{6}xVS?cKAV`33h)$E*#Q;C^x%`+j5xex&GFqlMULZp5ooIpHO90eu zNWl9bvb1+}r(!JzqqOl6o`L`Q3%epvk<@dp^V=E3mQ-&eOtWX=@G0+D#9%#(huO|k zHiXh5>Y6rH>W}1Jfv*K&UW})Z=ar+>+eo2iP$X>~i{4d1qD5J4&t(!ETJ6b}A5N zf&CM*v-%hd$W9)Oo>)aa9Db6nLx$B2VKnyH16CjR{Xef*`Tk6zhJYmRN;P@-r);=r zslaj@>%lon>36fD4z%1(vy2jP>3J%c`&@|Cz_foz{c5;+&*~Ee8wDytFF4SPT}SH?ltF7<}X-*B$Lhz;2l^hGqB=*lxJ*L3=QiN9rC>oKv|p zI1d2Pu&~wgajEy0Q`e=5CA&rlP`CeFijhT5LvR*I442|)-eK{4vjT3Ov~c@R1J-s0 zXcoIH@FHFRmx*oH<`NKShNrBW z&o?vEjt97}sJ1CkO7QcJw=k87BLjX{DIpcn3Bc$$$r;(1eJm@44-cnbiP6kN9}9pb zMjdiCu`r+EDptPs&DEj{63}OyP+S&HI7=wQ>N=K_2P{4F)Dw#lF?8hrQ*k8p;j&Q( zMTZ)^Uiv1Vj1@Jz2rK9eA(*QFJswwr+Jvm$R2-A5r8NK4)CtbpLPAp{(1LpHS3T35 zaEcJzU>tH{wiiW=-~V;)M;>F@7uqthT^gu>OR;KDJCxTNm{JBo22kY&U^=N*PP!Dr zE9a~Z7rDvp(k|RdHo{DtiU)Tn94J-^fQ5H*8$dm(4HAa8QpmuQa_5$=y*pTYEa8EC z$;;)77prO%)+nr`lnJ-NoJVhfeK53DEV!YH$~iAz4hexrD-Ib*V&HJ+tgIX&m`=lWZ%*Y#QUj;n!c%U3Lqb z%YTHhUKbQ-T>ElQkqF@X#(1!WwKTJV6SSd2&A#WhL{RNvR^hLZ{ywFMWs{AUf6TE1 zKv26MP5wIZfiXnOP`O+b$?znkR4{3E<}*j_Sdo+j<(;NNA58&S^E-ELw4vU1A)9_9 zhhO>QRF6flnl}S})2lZeKPd#Fk~$GS<(vK-eUoIPck;%)BCy*xM6vEsFHo~U5c3cm z>5Y(J3#l5#clt-jy6Q7A45s%;iMCR@#wI-7=>C7}@L>d=-93MO&jc%5fRj5Fpm=iO z3Lzhk^r+j{SZ6nxjN{eVQ+fLmT64q@pWv|geO5}eEZ=6F^lKH*x16|)vHx>yR{uLT z!`B}zoZ^cbq^PEJDe!AOUa46~KQ-_iQ>uGUWUN!f`)!pW#s7bx;PTU+57zls8?5P` zH)9>4`p=rT6tdgHysBdWUFM(zgEsNZG=kE4nuqzL?!*B##qYNN0p|P4pPHnaf6v_! z4>+#F@9E}0oDZBD&;*DJq06jA=~H&wuS^UnZm^9?j}uO^r%J?KHLZid618>`8E3Lt z5JveDizUVhYQ%q+Ui<3BiL5boV`;45?u!nrZLP{}*Of4T&A*;Ud;;RxXW9X*lgU2H z_{4%-Hbuq}IS~vCrqKgTv1|XE?(XhIZ#DSI@k>K4nh}h&#VYFvs7-va_=Ikl|AGNG zk7AVoi*HNzElwmE7F{t7q7S&SqF>(J^0B{(BMG|;4~$2bFfLF2zK~5F)VpV5mK3{7 z@3i`$q@p#^Px?J3t<$yH-^WDj zt6X#s__7!`zszlLYE<6ir~kaJ^u}r5XG;Gt7W1-Nq^;idb<19AAA?X%AXc1hx0e6| zf_KSD@bTHN#nitJP!lFgN&7Ee{LBy(UA!J;13prMcI>$Y4AsB0=59)-5He60{p;{y z;6d!Pt~9@0pXKqVeW|@a$P7;IoJ{PbPlvGB<4#N>Gxb%ot{GIds}B>UyjBVcq?}UK z9&qQdfVaX3ut!pq^*e8kCE=)7%R$eZhc$$scw}RkxpORi-vSSF=m<&d6a6j<;xoU$ zdp##oe|E31mOYhzOgr2uK&nTFuD~a;JU9r8DY(GTxNqGZ=C>jP7(_DjW+lip9`+*`zbCZ}fSibq~T>M0qHE7j5 z;R`ACX<{G!_4;mE1Bd^@#ZT^vS&uNVks7mV$55!a>k)*u>7#{Cq(aCRD26{`-5|F% zEQJp|JFD3zm>xw8?dO&l9xRu2eb|@rm>pdB9#1F3a!-5~#-Q~f8u09>Swc|y4W*)T zRC7}ylkNHqM%RtbFK1!HXuLP|;X#p5c;#OH)?pjNsCW%58)cdNh=#8YHNQKUY6RKq zVwkSCWb5+wUSDQCJH8UPEp>?E`;nC&dARh4OsHv71vxs{dm6DH<#o9a1q`fv&6=*4 zWR{tuoUDyG45a%F&Zk0!3?lsD-;JOA4>Qty?6x)n$DGquopig@el2L*a3#O&#H13e zM^9s%1>E`TeU*5qPA`wC>QKFgCD$36G9oADM_=gArVoXVb+`m)KCFiV6%mx0)aJ@O zhkgIwy8tG(*jnrr{heZ!1AQK&AP4(Aig)<)w{JB)WHB_pvEE^MB{}Ih*s|q}{Hzxc zWJxKB8cbbXS?mvGx>7u@VWAbv0!lq}$x15rRZOa``qc&urvmCPJb%+x;PgQ^NQ}gn z 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%0AXzp^PiQd{Mbk^rJ$l>sLxLVK~fHMt$!iEl?t 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 Ys$Q+cn-lwU9Bf9Co#WS!PLfmp2NVaAPyhe` literal 0 HcmV?d00001 diff --git a/packages/officesupplies/images/hanger1.png b/packages/officesupplies/images/hanger1.png new file mode 100644 index 0000000000000000000000000000000000000000..70e1dc5d151cc8197cf712268107f53a56e4b675 GIT binary patch literal 16286 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 literal 0 HcmV?d00001 diff --git a/packages/officesupplies/images/hanger2.png b/packages/officesupplies/images/hanger2.png new file mode 100644 index 0000000000000000000000000000000000000000..d61c87b000ecd3d30721c10c70b87e091dd0d26b GIT binary patch literal 15956 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 FzW@wFP2~Up literal 0 HcmV?d00001 diff --git a/packages/officesupplies/images/hanger3.png b/packages/officesupplies/images/hanger3.png new file mode 100644 index 0000000000000000000000000000000000000000..652d467e4b781ce81e6c3431fba96f1bb610dec8 GIT binary patch literal 16013 zcmch8c|4T;zxOrBv}n+38w!yUBSIrg*@Z;iau=qQB~mg7VI)zu>{}Qi?h+w;wiGGr z5ZQ?^_Uuc{^S!Roea`uvXF1R7JoocQHP?6ftnbhAy}nnE_4PD%Zs*w!LC{VuO;rO3 zVy3}=wz7f|Yeid6@Xxk8n#K+gBq0RxFdUS7NjjoLhc;+o! z(=9%@sDt+2#@aM_k&I%J`eea$oieVLb)4M6d&An5ljw9+(sD1)w&EyVPbR}PC`rjn zLb;-1NEEltYDCT7mRg|BnanZ|2(#S$-PIC$V48*gcgp@2NH z)1r^SKaeUO{B?i|h6pLl;HMz=A0LE5Fuxgb06Q_b|8s+WB)|h^o7+wgH~2$+7i1b|c2-Os1r_RqPYWC8pWjHY zic-?eaa~9YpM7t|4Etq6rp`HRLfFN#LSRj%_I#*NB?cxx%s=ceymsqZU*C+`h*qdd z@JDzxx#;6cPT-uz-i?KZu!$%GOsOFRR3(14FN+_dQ04cJBai#+%f42xpoM;o3y5|c zO?`Gx6a@@a@r~JCwDzhjJ!UR$Ren6)5nYFZX*Pdc`Ga?4`rN4U_^H|;6G!MpKa3rV z-J@MvdLsKqwPp|0rs=j!xI`gTxR~7KYG3Z`{A<;{MaFlsg$cqnoa`E$f^aK@zH_sU z(yQlyit{HOVeIK&rU+O(ODpILZ~O~U*UL1-Kf}4z2M;9=NYkJLO=)8up%>kV{D|N} zUS*<9<-5l)Va&u+bA>fMD58N^S=`WWp`W6BB52q!tUKo?Gs-O{H^|D1&(~u_ClmK; z>6r!(ys+MyL_#k*biGWJyI=nJ;8kaZTR;O&d|#tk~75ROu2nyebhyuA?%%zwlRitRLem7 zq>ZxNhH0B`>B7L(7MZn7e(2@1uE`YUigcm%1GUNvGt_gry^5Yv&Ga(il^^=_Wh72t z2#op*CxXd~*vvMi2G8iJbKc4lsp2MDQ0oWS-ll7c?}mNz;yp~YPkvtAv+N&awtC); zh=ndx>EWROdnPka_l`7dx$W1qgr#}K8K)Lh`jdDP#FbVWWHw#ZSst0OzILo-GN`zR z1iic_iiN6WU7YF0^L?$0eruOE)=GNM7sO!*CnkWX%cLUz4U&#m!u^uu-XC12Zqf&s zVGrNAQGzXPQ1i_?K}r`8aiI>Johr(Jm2BW2)8X2K>Yj3CLozZJ@>t2Sv2t1#LcqnC?%o|~j@|eS7;FyE)_X3l} zFgj}yw)=q>0m=DH5UxR{V|U(HwSH74*p_r60(1PlcV7Es%na9Su)|m41gzeStiQHk zzD4}0&wT@iJK$VKd|te@Mr`^y2w}lm7qn#FkGsqWdVB|OvJR5kDs8@Lq2U1%@$28e zZ<7XldLDZy;}MwOS=w2d`izSSW$TAMudy8FFIb*91&Iy`6eCXNB~&aod5mn z3jj25Ic3+E&!%W-RLf9XYCEJqu3D-zG0BcC8)`f&CK(_Owbp`lt+&!<+YxN~k$|&X z2JM}pbjMJ;Shdhb*LyUxNP~s|9MoC^FST*Lp0xw&ehQ)@-Tr~80GD&*kO#Y@XUO#d z=p>XL43D>%p7TmrbX;PS+T0|2GE3RtgKC~4I^HvXD^V9sE(R_quktPOjar-0oAjCC ztmC2DBIBmTzjJ<&KTnw*O22We9~MNUsUR$aN|#t2mk1RH%O-(87LDAZhf>zpP;lxJ5g1+5O1SaOusiF!N2ujw-)@NOZhSwS zu*4gpv@iyJQ!8=LL_o2~c;}6ve7k*_)!?snPP*l(TjuL^3frOepM?t0{QeOI-Ik2d z`?3UzGHqo6WPIZmnO85Yo!*r|O)aaHz^bHuKQ3!UYB_Z(tGEyU8Z`K9+9HG2+OVc1 zx`Yg+ujd{~eRpRI1Z)(2bK+Rw`@`>C6Z6Bwb7C4}6C(}s%}ShP9k2be4$aLtmvOGm z?3l)nXD48hmd$mJbryEnncqG-h}RFOS2&lmzAE8V66YB@N#IJ&+Y4hrRSRpkd$0aA4Zowz=KtOF~Cl%&_#kh`H>se)!@@*|O@KCGCoX>es{ z6ZVg>krerbPjZYyJwFv`P|ucC)3&tB^xOl_(P>6I=Y_55bjdEd+bDH?(Zji|mky0y z)3p}G_E+1N>D=WC&TB~=6jqSycx{_FE3ZBK=?*n)PPjxV7jsA2iHfr0P}FVV6Lt}4 zqBU!zhX2qN5S2)McQ{o%?EZC4TCKNmW9*BQR`l~*$>SMPpr~9q+EkF+8?k3(KDEF^ z>zpU9X`#g7Yp^9m1RU{Rxp6~=UMj&#dO1Dq=2es9b_L4l)frIXC)an8UuB$tDTp<( zhutR%kJj3UmL7B#=t?_-`JOvAKcXe3mca~E*Hf`LI$q=5C&x2S97Nll(9LbBE*4cC zt!i21S-N-&0FDwyFgxU8B{TZXzO7Hn{X+9XS=e<+r#4#et1QkvV_*e=Vi@S3!HzwZ zzM}tnQEItVSi#s+Kz6GmK=py9mxo1$f~f=dcbiUZLR;+9Qx66VWV2;q`~Ky5Htv9 z<+t)CseM@q#h+G7(%Jc9SuS`ecYj`eNH3jVV~?sy4Nv7nUs`*75L$LRUEJqD@qBju zymrU_QNpCQn54GYn%2I_^;eR?ookX%b{J;nNYj4WwA4}y0EG=E;FnTS{19%PPj)2R znH(8UBIkK0Fs*|y%O{|#GsEv1Xm{u-my9iSt>G#rI<(N;TieY97BYOJHr|BawR-5a ztyj)D>^`;XY`I)bmJ|yRx6i~jlR9bHEEzg+$%<)rxwAy>#_A`D#4~sO`1&`FP*MJM zdd^^0T(K8ZH^g5YfBma{dY3NRqTZ6~Rn#@TyuinSu2Xj_?|S{Kj17cpHKhkNHY>H% z7j6&~Adbt`SJs}5!SlpLkdxVq+U#$`+#Uiz9#T3VS;EXiVWxGsu~eie@~vuQlDE4pM+sqiw*od*tf zVQR2D2HW2SSltz;qB0u?rz(Eg-S1Hv+i2HwKrc5aIw{nqVN0KB^m=swqt-R&B)7X9 zX+o8~DwT9{^y{YjF#%Mjm_@d9qgG3mpO64mzxlH#B~vrl4pk)HoDLp==b5imS7A)6 zB=7|KQmyYJ&S+kA4Qj5KcB1}xZ7#-iOy+S_0OZmAhepVHf@l=^WYLYSgEr7XQGnayB8h0vyVd{u6XvdV!n@1(aZ`oG679-N_@Ly zkHiCtgAp^#2U<~ZeEjd8Rq_9E{{QqWQPOY>G#>cFWAgc(J9V948;$PVi(swul7i}d$5Ah%uuoM%}9Ajs&2r2S5 zpVg!gR@fR_@Q~xfRWv+7ChQ-Dw*KCP@IdB~gah+Ocx)wkVGxljC|(|iH?5y8)TGP- zZw4NMIsWI(5Ai^F7CiKu*x%14>CCX&(7$<;AqyJl3u?Sq!--NHOJNx&kiGD`Yf1RE zJ&>24S$mzXXpFzX=g5$h!SPw~T5sNJ6LaDE+rx4|=Y6=kW7LlvnP=-9Dl+bMW8d6C z5f?jMMhE#lA8Pag&}=2iPQCNCxzmNC4k+F#c{Cn-Q^j4f)|bKA@?``5-p)j=w6m8Z zuC%xEj{QAeERX8a!<%$w4i&32%*zyC8BdzwaiY?we;jH*ab{B+woHF)P3qMYl`q8X4^X|bSy#bn&0R>*%~CLao7!s3)jf#ED=snj z2zsZ)spRu>s~;%};^Xm!0d$~=JMW@K`y^H0pmHJicq|*&mLdhaTxLiE- z8Ta|jd+U?c$UDKQD!8P|YJbvYEes1@sMMnbZ@&f~>-}a+$H(6!yCvV=Mai-u$??0RJs!rBxNcLj zz`C}tc{k+Zr~3r#Mg?o%>owa>hgs5wd6~O+$9z`&>HFF9E)+ePfg)eD?s6)!;4!!T)CRJi|oDeeU)ZLZj8io`W) zVitVo#^k$S;~9yVF>j5&q{X6oShn>3Smm?MB{Y7w#P-rz@gButyZ!O8nbVU_$L^G; z30&2{9=QRKhi@eoRJ9i;4t;vs@cw)aYH;TCOK?us$_cI_UI&xtw+#Yp#tDH$dq!!j4DO?!P?+)r`D_d4)L(X^gE`j zjEj4Y<){pKtcYNEuIrRDgIQMCHNH3B?x@OSpLUHNsu~U;NyA zdGMX()B?xoe%j(IIuW?N3n#!YdHYiAS3sLrHm$5Qe%dydDvdzTeR zNdUUp%U2Gqq^CvE-Q8}=FLX<@w=`Ndg$*Syx-unsI4=3%*<|*+0;u2vhL)@&Jd_d> zgwK6n%dsgm<4;*L>^A#(k~BP9(hA7#H}+KTfyFybp;rhOi8jS_Ot)&a1)D5Z4rsQN znk9&KEcOb5JRIOv({uHmSJ|G?x>}pWbJKIdl6|77><)+f@J|lMET^cx!V#0YRJc^=*j90rR&xV>Todwmy_k4XYoMSLTzf8Jx zJ<~kP@A4_Uaqm4EOzq=l&XUh%F24;R(+pZUCaike&a7b94XNN9k6-RJe$K90-LL)hFl2Dw`%0_koq3kW6D-!hy){{g>k(xSd#79x>;{_V6Js;+eWw-1 zaJ%4)Rb`cTaPc}>V8NrUWbFO4>r!n`hI8W_JuVqCF@v=A1upf z`-GwjN-gMlHpJf*^cIE}MZe$C9OluumC2L^G zJu<2M^nShy?`X_#e4B?JkxoCHS@6tb|5)YxS&a5k{wm ze`Tw7iMcLW#kX}ymfc6{T} z#`X~{Oemi&?fmkhwO71sgMjU5mVL;A(RXYSRbw{|^e8<%ps;Qwxw?Rjqx%vxcmryU z67oHRlciX-*WBK;Y`AzwZdmHa)bQ+Ok;u z($#l84?A~b%hip~_PnD^x8H?GwE7gEVD|&gBdzuN&o`H)t!Zr(<&?L%xW&H?&5-4u zocw;jByjeIEPcLm$^C+Mhx4Ixf>fVk{enf%^f1Lw^}2;9jV(E~BpR02xepBGDO+mk z6|==GuJ-EXSkafhCdSr$7->w~PXm3-Wo9o;-=n&E;D{Hzca+H_<=mWNChh0a7rgH5 z5sN>Jmdh{a(@VY%D!!KFzn$omvcoaS?ih<8R!6&Ayh&{}rFXhicM=!IvE7HIJ&o*e(vsr6`?Ms*M#Haut?-*A}Z1y^`RFDym3 zl+FnY?Ko*P}|3oXFvzE zkZFYF^97ZYY5lYRZgfrk8opCEhu5sjiMvJ%^KKqdPs(ODq#o@>Jtq|p@Oy%fG&smp^LK~0a?UWJC{bOg`Yvj(rd2R=32Wv=! z?v&z}4CQjARP17lu&>r1Q*O2gs6MOjR1}Q`&bU~;<%D~pVxI?^BQM$qkB?&)Z&c@f z@#x)3>Vfg#b#SheMWW?Gb0pU0%9jr{#7!CI}gH3z}Zf62ob-9H8!n5pMI zA*E$JuS7G)D%t(j&ZXB0nLk>DB|AAhn>QMstz0=N! zJ>2v)e2&=^%Y*`so19~?S%ly-5Ae4T_?;+X3@1Obz6R)lee2PyIq~wyIq1JmV#nY6 z(OyCDkxmFyQXybc`1dAm5E+9&^BsiXMMY>QPTRe={BNt-3O0emvN|s@JlpAT>j>{y zYWSq^xreZgkga;yX?mu<21qm-zxCh*Aq_kX4u@y3AU9xPC4lc?wf^H&l}4ulSom8> z%ej#JxS<$W4sarbWoj5^1{K`%Au@!B%y2g+d>(}D0Q~fO_1_}ITuq5U3%%H(~PMo{Cxc6Fznp+NH!FD(V{yUI8x#>a2Fm z2hleeA{#OBF84S9kta8%^LcqO4rQ{9p{GWFYQWcC+}4?&_3-WS;%36eB1NM=Yxq|7 zTX|t1#Y{_Zq;Su)iLFXtURUu7(zM*YyGyGv$?n>2_%uudN9s2T01BTbbCV}-D>2cp!inr~AlI#?Pn&6c{ZGh5IKN1YwQ4tvc;DrDJfDPEo3=;sD z1$%e%KxcYf)e&-l1RnT_1z_c2F+nZ~b)faNB@6J{!{W!f@TQT41)Ua|qktbeNuo*D z3M?Lv!M8~VXIO$F*}7#@0CPofj0dtyC!xst1qshKNU~!rGgkz?A9&c51XMmi;x|22{2BMVyW<$l0v6a{t-%AwZwdcJDjs0Z*Omle zS|4~BY|ek#b2>e)34$fK)CiJ8x{+))Q2F1U!Q`gs2%ob2QGJ6tgHc!lA8I}^A z^hdkPt#uy9lSC{h6vjZra;*h{#1euD+v*4~_zM8bVBf58TcDq4sL$#^N$TOtcWl|Op7r3FAYXN zy8H<0zX`5=<+c|(p~$Ag;|5R8L&JN->|7xsL*O_j+n_SCHeoUAklANo}YWA zS!^q$+a;vSoKP0Y@U=U517G^02uUbhT31T?JGYE_gHKQXac3d$`&U%_*PT_E5A=x+ zqp$Zl+;3^Ww^7(37kaz>U7W)7FP9DfkkRTvdI)`~dfU2_U0-p0*X>pM+)B9&-9lKQ zq|CFe`?HDAPbd0v`CX5e_T^vB^}UJozPm&jFXK9?)IG^i-TS$kdZ*BHfgcFF>q>{( zJf$%zK}!nCav1NxrTC$EGcMnx`*XhUmK*7pt_)O&g9B@H*ew<4(&@lP1?9%b^N@}d zz?~B>ce0MQLs~G z5GwwecaZB8b^69tWDQo(-D;YP>BX!2=4`Cxsq&{Vz)phk<2F-V%#_QRU}kVNpoymJ zLVi_{FR7yf+JT7#Yu$yU zmIZkziEI8MQh(7Til&xk^%}PDUW$N&S3sUSgM;4Hq zbHXI3UVrs$KK`_~;%gE$tIV&|bVlS-ua&?zB}P3W8g3G7xY#YrLMUhK{%OqfpnfKX zH2nPjEjC%FM0>^_@OeYi?G(?eY_j`kOTSdafqv>$N%qigvkx1_8}AWIpPG1n`)N&& zSMUC86EK8f~JK?4de^fL0Muvqjt-7jy!g=-+vXc*d5~QO@ogU5# zU;>nnEd8?2-RoO@%dUCiymLkh*Ue>MqUb*%^-76Vkseu=I!!4SUXxFF#Ba%f95mNI zBM)9*w>IkGD|CMQQ%*Aas*)+sgTOuqhH|cXzSWAjUA$LtamLXhvk_9?manxTc1({o zA(2lWvjBX+rP0e{J5d$y7-SZ5!pg4Jo0wO;3zrP2te#fbghx#sla@i5EGsVq00z(k zFm#2^{bIoz4oCtF?l`7JL#Sy#r?m_K2s#1tbr~ z6!5V=yKgm$*I(t;U-*4_42l;gp0{%x4YIrTNLz~aqWH~CQN>|VPa>9B053do4x93! zEi&)lV0&r&Z6od1IoKIwyu3{2Bds4m6}D0tmapC39MT=qbZ=yg!=cDXc$u&GmPH7y+@Eduj}0o1mG+fc62Z77u7dTHjPSA|M0mJKjNl z$<`#bkP|B8A< zDOSrw><6xLT#lG=dv`Kss~oJZ=V&K`Mhs0_GK}q4d#&Ap|^ZpOdEu z7e7Z;Q}DlSsEUseCov3NDb9BKMz0hL!GwXOfm6p>B91+B7m4qn@8Wtewy&7sCVGOh z9Z>T^&EV7mBX}Miq@oJ1r1#a*rM3gZa?s{3Z|ytIN{9&AC_ro`=O28&ffY-nMAtHoU=L;2&8om+6jpVies2o?3gFA z>Hu|QF#jMKAUjhsH;1xqJJwz0l`QqKq+K&d4>@?J-{xd;G#TzmH!7~gZVQl z{-pHIFLWI1US9?jK|rPp{!NT5&30x(;ht}% zJi9v3u=R+0Fg!W#V8w@%{c+Y@Um79XZvi5!tbZYf#6dGJx!qHrc^-r!Su=6?TDuNY zfFzZURFZzz$VU)aPiWnAAL6xkb5Sf;#B82adJm&Qsp2d4o|LiUi*>7p$_7DR_HOj- z`sEE1tN8j&4Nci!Kl$r3obW&_g=HzL;GPuJB48}c0kwe=wJB|8o!%nzXTivnA#@YSqs5c)#oFsqkKEXO8 z!tWx`@qF2`2%*(<*9z3=4jG1S!5~?`InU5T;MmT}Py2EU0#LZ@wOEEKuYC@JgV3QL zHs-iupKQk1G4SC<%Pf^6!0ze<0{r{qNe3Zf3t~ayBFF-f>Q^7y@iN^@uI31sy~Xg} zsWGL`J{iC&hVKd(RuROKwfEI*!Wm5o{m7sX)R&qqRCwo;MdXD8Ne~--%(pr)TGLnV zNFSGX_FXtpdYuF}qmZK-BT#{()319mgb|FFvIfmeVF2uB^&)~3vYgw&s++6Sd@I=+ zk;bb7P6m0Kq-N6cep=R z+7Fhsm&TPNnQr*~NOL_u^iacw~i1-9>oD|51`IFj>#c+vWB?^0cdAa}ST$$rrE4O1PX z4CzFu3_@Hz4?2)Z5uFs~-0#w~!4br%plBTd9YnKaG?F_ADTb3D1{A1XF-U6n5(BA( znD=oRR2keY$Z)Vpo*4P$VDyLQo5VCzm~q;OZx2xaa!49;11^(@-6X}VL(U?`u`rw~ z2-175VVM+b*Z{)VZ~&A%bj9dxPq1A)kG##8>w&cua4GS{k}_iphXSp_HUcyy!uuL7 zuVleVsp0}?2XI{=k#q~o6tvvm$g1z--UiZ*AyKp^1BLU^r@JLXm+Vls`;f{R(}kN@==4lA4!h%^_uRikR+@sN$piUi7Y>zjKUe~DHB4+r#7IdoLa z+n`|&0TP0(ZEwPqB0l~#t?4_yK6S}n_ZTDN6QA+%pr7tR*XV9WIq?GsHr(sYTo;U<0t?M}4Gw^|FT{8-}D1K`ht7l2OCU;o$l) z^EGH!MI4n8Sx_Mj)sIPq9K0o;bnhjrA zP5(M|8FnLKaw6rNz60=!Zg^HePX}jLIf~w#f0GR!%lhx z=wb!Vm*H5$0_NR}k@TMja`|J4Ga#22+NXHlV%s#qO$*T;kmBHOR=fx}6ek;aFnZ!L zqlV|ft!x||a@U0z+5X7&{q8UQ&n0T0@6EYW5hEUXE5ovTA?P47z3e<#n; zEG~$)*#S_+{9~l4_{`^=1o@2acJ>JX;_OEaPCM&k1_YcWNu2xpZPS zvkh6w#d_WfwbWe!C*F0xMHC<&>=ldC16b9z@0Op(Fk0 zogu$Xa;#0u2_*8_zvbHnx>KAZ;_Elom_X)2@erkT&GM*JI1Ju!VgjWNp_$UI;lv-3 z0Zc^N7TYHpJ))UKHf$AR{zpqcBIlfF5!imLA35qON6Kv$8Ggb*d##Wnwc+Wul+~rV zcgr1ck#4_htDxU&D@~2O=M>boZE_c6njSix)$T>HG=3~e@wYM{KNseI!g6avKFGYW zyJ&HxOhY~{zDT*gE*n&IqIGw^fJ~1VWa>HD9bE7NH1(7tX9q+1WJE2X(pc`(PgL@M zz-LYM{)^6Jqp{4o10N4|&B6yG@ZPBNsta5)I`sk$cwvR0OFqcbn-0sL>_4%%wwc79 zelniM7(1zO%+wJys^WO7%WxA(5d?2#{4t%8F#b7cg@zTZht;3L1d{h3pwbEs-4DZ* z&K0}8v`Jq-2Kc|cGYXNT1bYzHD!DQkDDspogA!9nf@;SJX0Bo7D9)6Vj6rZ+6{iR! zibA-9JR|d-vD4ujM7|-kNhVuHqN9>3N5lC|eP%Pj79N9->9_+S;IQjhA8_ES*S}~A z-cdq$t< z(ZjykZX1_Zx`lyX!MTamQO@FNgWa#|TY+k-_@hU6OOq@8=I^7Yy_cKe#>9`*eF);w z$9&&m2=SGZO`pX_hWRaj6NZQ%y$cYXT!+N)WJ4|+AkG~(z~_~KhTR|)Dl7-GwP}GI?Qw-7h--+Pkq6v)n6nExm2 zB0@?o^)waBMC3x8bg89vE411Uocfu$5D}qmNDK6|X`+njm{j}6>><7u5bhJI8!@)c z%pNT9@W-tN8@Y(50BGLUj88o_hN%EV&`sN1@rud6uzLjCFTaK9WC zb<<~+9S#Q~cR~vD1zZWvyEViPmJ9)bYB3^*={0MDwB;mx45;q3J1ix&h{)d_A?Ynw?N3X$#Jr&m+m{JY%4FbnkoiIg5%?o9rLm=&POUSby$?v!nGg&0FCbGs0j>SFB zTgbATPt+V43}s6^=S%`Z^`UqmvsHR?Rvp=wLCfJ9OSjQtJw%DI$w5|-?gs~zFcDtC zqR9t=%tj7*Q1@3rjpuHJI(4OCE7aL!%vU3XJnsToG2!{#!#*vvl|Mq@lq!B|I~16E z3d2_eg1BO9@mXo2UJ3{w1l9y0hSCRio*le*pM!-W#h~*B$f?_t$34@!lK8{O5bU%C zX{YI03f-Lb)J2hA51={db4}yvW@5ri0$$XNd)hWL5 z-1CRq15I>(M5;ZsGmaZI2SQd5`^^-%QZ@h<6cwVE&rFFDtE>%h%4!BeT!#POTzZBy zQ^Lu&h_v7SG>u{=>ndzMDMeNf1VL|#fZ;Tb6W5+`p&G?N(raGXCcDopt#l`P+XN3P z=gHzSP*-|y)8?r3lJW|JP4};g=NRGt>(7Uv4ycgyUzSwA8=QuOBNHCe?SIT zHKlW;QhN0qlKmU94;|nDb`hsFfJqP(hXy|=MDRlh*bb4+c>ngBgfy<7ij43-wf}85 zAsiOyKom(g0nZUdf8R|6MMM!B+R}VSZm7cC#^%*#%tc1Zt<$XeuHRx-8%h(JlFxHi zytsJjzz1Q7>=rrqyV1><)nk|G2c?XvT(OhQ2~92e9I&_s!FdMdu2EI1c3@X1rTsc3 zDWNGkg%kEc)Gtx$+7CuF>o6MUq=S3iy-g5iFnrr+Jf;2SSJ$&{O-Yn?l8!DsSZH+B zLj@;C`of`bE5?zFJW%taFe|Hv;=3=N5JM^4hADrRbs<~-)OP4&v3{31FS)Y%$AM3z z`rz9?97d$im5ihBa>3{w+rT{j$kc_7ihxm zi8L-ULFIE4vz`NvM>0WV9F_rvD7U~+{JbXTc5S9N2rw*8L(;sKK-3}S@jRhG=lZ_y zK}HkXm$xXUkEyZjE@ED6#yny+XyKlDt3E6^bU?>m5sr20BtgowN@a9ma>}I2(r6+r z;d{eO-<$0i)8N~qGkt+Vn2U<(dby%-)X@H*=2l%2@qaZ^(Q|_`sfjDd$}%^)WVBo` z-e;wlbEOsW@ii_`9`~$3a`c3AhsM6jzO#~;uEr@9$zBV^%YGxs5Y30LbGo{xjjPfk zyWVAIby6swU8Xgcq|y^erB`8R3Gus2L?$QjP2O;*hQ*I9#Wcx_l?i zEMs;j*XE68EG=8&23Nz&CqfgN-e+$l>%WLcLsvRQ4^T~w(h^?F4xW4GKx%cxLxHE| zv5;qp@80srHR*FHQe`QXeSw=lPi1yl@KS97J%k`Rfep<4Mo&kD=op8o%<``OJNXaL zgxq!zFx|?%pOfi9dFa0GbF^XScYV2nnOx-h4)EyBAhEQPQ2yXFwM}k!iADKF+w82( zV=x>2RbM2ScwTS%xhG|MMZ9-}Sk`)ly{-`P^BpTKevZA+laH1f4+OLQm zYyyM#783rf*dTooWZK_e(SiRzEBZhB$^U9acR#n&1cHI2N5FjxXh}@6b4Sv~s-1@y zzJUrvYI|*z#FBVj4GJEtRboP_%+3;**ntGv!YREQUrCicb7x_~NrdnSL>kq+t1~qVd0#$w9Q(U(?TQf@rmoM4L(DstbG$OjE^lyDb~Y zYj7^D@-LVl4B3u(aq2BZYt|qq5h427wCPu(V;E912lWmdmn_b}M0JXb*f!~=)46bT!diGK(FYK z?Yp~j`gUJIg077#a5H9_IFpn6hs~==c?i-wwxzHK3*iM9UQzDW1SA^<$LT1hUr*Tp z5$k|H)B=SfL2BUu+*HJJ1vbUQ1(tS)5z^JeL5(N$-E>XfAG~!D=cJdOKP}G#!*n2e z{&%BGwE908>=)j z=8(TmdcI9Lsd(iR!yofv@skwua-YgkIBy-QmyTmewX9ta_~qT@)77th^?tP-Q?4p* zNncVq_Slla3#c}v%>5qVy>sDctk;*!1By`&GshnoRV|wsaSiAT#Ha&q$XDM6q({%0 z56`|hF+31tbkl*tdr-TI(jhu7BxSP8(lK3vT3I7;N4wP8rVs@NZN5OB3QdB zR?{Ib9xM}nhZ5^Ann3PZ?Hv?~AU9sASOW7%&P~Qrak5RS>-)3Wrawn0OU5=fIt-O- zkk%N!*%DuIeK26hxsuT~i_qJj&dR?m+j3^-L{@V$P_d=T`6*W-h;FiN%>Ca#C68^T z=Z}o;?$UEx{bL}Z$+a{)C~vJAQopQ$d(5c32E7@-4-4GMQ*2n^(hLe_LaV)L?)0s@ z*dRJ&)alu5`icX%9}=y#&+e&}(`&v>7Jhrv^UuRIlR#~j7j*i*Yl)PyFDt9e_==ux z@BX}?g-1Et0_c(2XXad?^SD0X;vnQmg zCS-XRSA{{mRYY#fmcY#RN|v>P6F!=>5K$9r7-4&Pv|TzfFjrHjziStZU^eZQ8(F^y%UeQa9Bs` z@pfYoI@x;PgOR&|COW_oQL3Cff8dqXfVQOyP`2?u%`PR=9k7J@X1J`h?HXX*izR^q!RSw;J z@>$k_OyC^#jEzkc&goT%%80rTS>)pQZJ#(a!0D~VtNyM%2gsub6(>!qRyUNj+&|B0 znCHk{QE^k8iSM$pxhGcD0@N2y8e8VXv++*(}1(mgV z9LHY9qfx{Vw5pG{Zp^p4uA%>;lDn9|D>QC^1)w9IfHn}KOydYEw&pd$lL@?pOi(@v zR6Zh<3N`|O#SATnCs`MM{W*kC3tDe8rBLp#8;c=9HdHQYc(62$LuedS1tI!hvH@x$ zjHTMi%Tq{s|t$K4}^c9{S66#6H+l zK+L-Bd@!1vc8EDfc*GodI3h}T^SIOz8;#wU;UQS4Sdc-Xux$xJ{}-X*=c-W%&tzAw zRRZ;}*M&WS#6A=oCe<{86d#dV`#p+~iD)$3v|!h~;kcia!~@R1^r5^#=|mCn%~cIv zXKt?BI686P*VQ(yIbY8Huz!sL+xZZ*bQ5MBq|qbympbg#O#DR0P~I>c1Zw<jK5}BMsHW2(fD#RF4-7wUJ%WqGKJz8f5Uvyt{Mk8^?G6fgdAbM>b=?|^;hPgH+V-#W-%ohj}?V*RH z+#sdI)^_#t{d&3A7fYU;-}KYQJUM$_TvFMa@He>|f8Klb#4ID$EV%!SPqYD8jors>5q6vC)sq;q--@x?8?&fnDz36#`aeHX-$i8e28LnS2oI zW!?9ko?i=xd8WBgRrrYbqZL!8Y7MS8h?W<-X>Iq!cd&8K;I^px+?thTV)8*z9kZ9W zcT@-g7LQx~Hu2c2X|eKmbuV;n^m!Z{uPCAsv+c6z4te#lj*Ft~fCtgj{NthbKHQY% zO!^;5bC#xYuJTwm6NeMd8#>gw;&YinTG8h$y~{`E8`;F+)6ZX!_bkoI+B!76^*6uo zoyG{*p&*7A&b=rW`5YkJL(*dEp?{zZ z8;K36PpTg|H*2r0wGS&ZSHY3Uk#*M$pSSk6buJW*NtSLC4+!qwW66$)dh2bEmj#r6 zvwbJy*(>Wj9k=h|_^N99FPGLK4}IAI=4EDGIFlCoy0tl%2c`&4;bXfFEQ+5@P>wJx z3t!RKzD~I)P$qw4J#7zIXzh-w>#VcXAo$ z)l2yBn~#P1txgzKdFM)P^0#v{t%}-KUY*1g;UoxxjbRAd?xJTZ{q^FhQd>)L{smMC zeIX3%ExN?`Y>7t^>6PDtbnf?P`01n%7Y)92PMN8bqlzS^%fcfr7ox( zO^mc=ik>WYojJ%nd*ny%y&g(oXaAjrNNgCM#s?PXA?T!RE5G1^N|hpT62VAyN>~gk zYIUdX6QVCHt$J*B4U9NtH#(6PN{C2a(K&j(W3nz=AgH56aff`_9R~g$SoI17cceT{ zc>MTagTr#yDO2o*O2oozOpW5knLDNSHm#4xwlRV_h}6EV^fPnYwKwXFtKR&UltdJw z)AE8vnq8)3JEFUPQ#=;%b+uU3IFGm5_*1>|(QK&#^2s%&OQ7i}+(!oQjmIb7UkI|X zIsNGK_f^jwIMQ+7@@`@Ja7{EjY~F}a!E(Oi?Va8ytjRbBs@0>8&_Nt-N_!U?q(|zV zHvNJU*psyr_e|ysN|#+ULxL9Y?hkZ!tVndA3(5>V5KqhQ8-b@Prd2J`ewz2!GGEC` za3*bT;aHvDR(=h}77l}eqNVO^!_xBxrL5^YJ8f(xjdXOve6TpPQ`5I3Fdm094fnV0 zXRBi^cepBk>1Ose6JkiN9x)VOp}el{Qrkm=;M+szru|ey6V_`@++Zn) zyi)gr3vYrSKfugdM)nN`9rz# z+|F83gYD>yk{bw8IY9&L%Tf|v3(bum-X5~szh!tlv1|k!ea=kJ-RhGqc-V8ID@A}9 z2lYI&n+l(oCV%~)DuL#9vgKq;I3v#?J6Q9?W0{teE#JC!(~=ljSzlzG zPS<+`3DYe-rWY@smc+=Gzkm67_hnyibTpTUn!O$^1M|X3eARnGwMfTn?MpUb$7li^ z5o?6ST+S8@d(a~Pnq@$p-#p#cX2o1gF2YW3m-B(QR4Ue>L2xG3a0Pa#&!HFzO=+Rl zF-(oQJa7gE_HaAG!9nvy#>RSohX3FNUY6M6>DM|tY1i;@1c60~GVQ~e0qyfw27X+A z)^_Tp1K6_%9`t?2LYvswTy81(3QnG*&@7AY*&xLh%(yfNB|c(^Wf@Fi<3gxd?2mnIIRG6&`2(IJVm9FN7(nU7Og81+eTg@utL#tCn{T zN%fW94Xo-+wtZ=Bni*=w3w-9mpHv0vF)>enmD4YpTTgQ`#vjLUojh_RbsysGq(SetDBEs2^jURUki>n z&Ol0J1L#eDMsK$EZ2z@(@2W2D3pcahAkc|_m7n2$SCRs1B8vF65bC+!ak<~;w?|%! zvV-9GNMJhN0CaI2*62Ry$((_Oe6&@jT5Ire)`_!aXx!jr!k;}}V0kCgEg5ls3UM+=S&h&GBU-?K0E66xsE}^MvSr)9j_>eqW zo#4Uuy%y@p-N(EroEQ4ZMY%rs{vq+@?tdterDhe1#pT z7ytHPw)OIi;BOQ;z)snuv}ElMY_{PQ z(yD8z*1k@SzS$duOhL_-z6-OZR+(xFd?sXqn;gyJIMopQM2GRsO%GRtd9fXneQjl{ z;CS$19n6a%k$9r;xasd^4ZW;zapeTiq~ zgHS%f!i+3vH-Qza$hdIbzr+QT)F7vwiK#8PpfY(BB=yHoL(B(z9Coe5!21)p!mQLz*Z$AH?_<* zSB#x*VBDBi%bnA&A1SwBKvVoTiP9~=H`BCtlDNw!Kz(S2;QdBwv{^(DH&X!Kwyj_D zhD5_VH(3ywfcIj;UI7T6JGCzcwa=ft za>=*~Zf)1_I4n2*EDt!G_--K~U3c^W;uvh6q5|#k0ZuHU_5Wt@-|z@ZjRpw7rRkqB z1>4gwyb2%Vm0uJ<`X_MswT|iPOQvkUWZ}K&Lcepl%0C7mT;ajy4@TrCA%GlshS(Wu zxe@^HJfep}r0df_zkB`LahO0;Fd%iA(5HDG*((AH)*%OUz(6eMH_0jSGW7r_77|dZ z<-ydl#=(N4(G+aFNt)X9-h#>7Dwo>Ell;K87v+85z9C<%5d^Sn6NPx-&GR0ial|IE z9B1@6eVa0s+3A`14CYdK1*5x3Vm5}~KgVa1G_K;+O{xqqJs zrMl|L(lBF%&o_D_PKN-eQ>U(ijX&XEB{FVWi_qa6EMm*QN<7+t0<&>Ry>{)r+Ym27 zvVy^5wbw51#JO%lM1z`16dGF?diz?5Z3XZKL~@HA4Tg(xD%W{CipV@uiJ~9Qw6)oa znGK3e4I*-Q@83d)Xa_RezTJ~h3THNMh+y1g@bkQkx12W6n*bhi5Wc2vC$;1_?;N^4 z2tiV(;co#5K=8FB3H?ePGpjms1sDs2h(Lgpc1?dGYgvP(9eNkhh3z4l0k~!j{ zK@Kas0Mrj|0@FYtVBi2NAkF-y08U_ql4@@RYb0AY=mCYWl1N0b(0EZqF$1h}!u&7* zy$z6o-r~AM6&&yoXdc}T^uhQU1ImD1jBdjozYRusgHnpM&wef_HQ9gNIuRISV1$?8 z|ICP?w}1SrRfcREKv{z|rn2RGvZYxgL!otZ6%gad>!t`JiV5q!-atH)X8VC=TOI44 z*~Ti6ItoyXcxng&4G8jE4W18*WMSD@PDX$uAP6V}@qh&)Ku`fYIKgrWNC!duUJsC; z?^cNt^@CYfvcKfo;t+fgNV!lRv4NQdzKuix&DYK2O02CVg{JNJ>Bo3~*sO zE#WEb#dnZl9Dv+a%T?Bfe2`hx9_!q!U%}BgOkB8MY4S!kOAJc8=0-?*)Os(^T|w|- z?B}~j@SbP=TNZGd_P5^z=N%C8#u0fh`FDR}0>9y0R|HN;A^1%h`1!Zp1ZT_t*%v|N zJ-b9XDz4uIUpT05_hXpg|3aw$g8?oU`Oa6_)g_NbBvAke~b(K67qi-oR&EU6z_4W zqJjela@XFmbOUBm8s;?CdWwQe7f1Q_^{Rb#E11h&>yvO>tBkl~F*vc-R?C{J>0vGJ zTbry~b5phpdU?d=iC-g&6%*_}lEPXY_hEIYKk)dmEVXKH6L>0b=)}sjpp?T(Zi&=t z<*~AwlxOz6tl7EoVCIKq)@1nu1rS}EJeQktK2v;afB8DJXi|Q?Phz!3`s=U`>np43 zT3rmklV$JHn(6FU!PWZH_TPiNy+_A`I|A!|Ag63); z!*5ULo{Ckj>{8a-%}vGR20ODNkh@pA%ZL|+F?Dhr>H}j#^WmzdZfpGo2a#tlZ{CDl zJ`RlXg{wNVmVEYgsPcf^PB?vudw%2|k!n7w66p6?7;s~aZg|wtG04-9cKF$NcdE>% zd+&z8ZQw}qbmT|=ub&1yz=6L))#Sl~KX6Xqt;*cUj20~FoiZ~~$!|N>B?OsZ9sUCI zsqL+C!=uBmGpx1=q;jESxWH>&G4Qe^3NJjCQg;>+)H$58zO2s za9HVJQln0PzgBqvfLqx`6qY@FPE(VU?5U-T2Dy6$eC1&sd$6yAb@(ud3bNTKcfCW< z8I-U};3=`zYju6gcl!3iUY>amBx@J=x}b!oKRk*Ir-h{N6ch^(g_34D1UYeyt= zDkh2&cuRkHoOv!y~1euCzwh zX#=Fnh%RESTiJH2p`*AI?jRV%N|n$d9NI5OmBwdhpU6P# zG3oa<)ngSHm=O*UYY22DI% z{51F{5ciCDR17@v9coOu%ekJvGt66|aqMw5CQwD>NwL-D8|(AZ7C*s7E~L_rd8Sdw zk1nAjRrCcwO9oVjT%AIhhUdS5T~0 z2d@w*OT&hv35+PjDOD*_(=uuIu^C;wBoYejSxNvYNS<9-^6QlGw1ce|KM47~Uw8c7 z32uKm>|kER9sbk^b{LbQqNouf@P~1F?1GjLf9E4Vhy+P~MXCoOSHyp{nluO-Q-`a1Z^mA0|vpS!XhOFqmVcwa-4lRBNOukVIhH%=WGNAr)-KdBj( z?8&Y#OzB-Ypp?81Wyc!?;*Aytw+tzyj5#}tVBf!m8vt$EjCC5Wm=zsSQPBI4&>`j| zV|s!`gIRGWk(&HJfdo?SU8!`t^D}`yzJ)7--;@+GQ@x9k@2`$FhUl{6Lf)qp#r!-^pRs`BVGp|mBvycCR`VDdro#at!){a+9|~Ks z1GfX-0SbSr{yT|F;Vo*ii-UM?q^o>J` zkO_PEs8_ZQd)y1SR{?T?8x=i#>_rs0svaYrRxjj&H_@cM|KQJyzq4Gqa6 zW)ZiK7O}-g7r|wm2;qm27zju*&7zQh)J>EfMdF6ZHZe}<_E9Ac-hgHBgsqAASB~?@s&QDXffayos za6UOwKzT?QpSMyGH+ZZZ%zAVdPAKFX9H&4JmwUIeK_J{>o6y*fn#(6v11CDzc2dBa ziq>G}1M?Ol1AzUafYY7l6`n+vPWO-k5t8~M5>0SJ(tvCxFLAIg*_`(yyTu!-f%-y> zNKp|rs9{Sq0}`wKnM-eEh9$=k=LTrap z{w!uoo|b(NETHFKa6F2bNj*bqQu9HIi~LN-yMy7e{%Jb!%8GCuENS=~!4k>2 z0Vz5MH1=>po?d4ctaid^Q;mSAzPHu2;ShiQzLm+8)mL!8QivLDX<%HtD~9z2CJHIMe~hIy?9OOY=JjGo@-hP3@wKUN~E!h|YiKaOpB zF=+Wel62I=IN5%kuQ7=&zZRKn8nI>h;hs}c#dV$B^bew<~2$W5MxM_iKY*XW-+0PW%n+z=*aUr>+GruiDFmG3cd`ypsbira1neK}y{ zv(yR+{EH*Uk#;wKE`}pG`iy*~VGQ z-@Xm{{LC))gb*+}*^UUWnnKug!E5T7fU)O$!Z?wXBlLlVHF^KK%k?Lf;9lKtj0}d2 z{5lqIY^accWXZxkSlp0xnn)cIynbWf(@&5Z50)O)x+UI!jjbTp$S+m-B-rjiDr|m% z_i8Btg-)nz>o%fe@4c%{KB&U38VhlDVTV+@4s|J|(*5 zxGU&38RfZar|e#*(U0-CD81SCu0l^)TaOX*b9>^yj8??=kEMCY#m7IFDA~Ou0>^Q+ zg3}du-bGs2d_romJqHWT281JPCI?Bm799^)J1qyoEUf!>wNM zOz9@YsKv%qt@(L9QCOYzjvM zO#HIj>aJLqMRTvqPL?%7&<*+ZtR*cd zbhZUUbu2QA2}iKEnfpaATyW#g7HIJtqIJj38jgw*#2@ReR*f7acMrdQRGcboGa>D; z=yaN)_FU0o)9F*l@U45~DZ_?ub;cl_D+|NbQg(2TcIcY(wpaR%>^!=wCfN7XJ05WF z3XnT7bpcNdGh1l7GU^b#yrOmoW^tQUqioY6_?&r)b^Gxhhaz}26IWkftT&y;H6b}R zG?wuUuF<>hZGk41cy=Ab8yF#;D>TP}JLi&?H*MR3cz(cR4_+T7qw96uH!a>a8hS2^ z-2ONiNQ4S`*}unXb5u-iQwzSTRBW~vp@BOYG;T*g3mw5&x~aq5uRoATe#nMg0mNAK z@%rUxAq*nn27s3k@;GDr)0!Hj!Q#$ZLXeJ8F@h!!Kywe^LgDs$U{h1)j0aJ1yAf4F zCPUB-XDwxYBr=4n4-+8;GBVKkeWJAfSgKD`YKzJ#^C{GBlXZDBzhJ43-`)(NFnibp za1jg z9%d%6-GVg?XT{XF_ZuOqmVX3`(Xk1P>0Rm8s}bZ47T-iwk1*XQRS0MZS)R*q!VL!! zGi$1!{1Mq&&RQESM;_>Ci(#FgLDtCuy}lg3_~+Y{r|(tULOW$o=OMuz|;EGYDRe)LiHj*;K-$0KG+Z;0~G5=ZAKrQPa#5A8@0&AyUuZ$N{0y< z1gp=di~!hrg~q~!R={5!6#oqU6-TY@Pm6s2WYV-Yrwlhj z7m(RIr;jI;BA%cst$MDkrpEe8VaI7#+$K?BLdbnk3SZ4z;&cBEZB(U;BrAUV8&7WX zeefs_Z3Id#VHI!ZF9g?JBfL<7tUQ$2ku|j84X8BWdao5IulsM-hM4gV-qz;GO^*PH zmib^-3lx`bP;fFkoHU8t&p@i-uoT({`jSGJs>epMUyi54hr)Va@U@7vW%5HV0vDo= zLPU*KfvRNzYAq0+@o6J;e_$d*P%>oi_ms6igIJfpf7$^;+GF+?(4DgG)R&XsD)!6G znisPnvBS|2P5Rx3?9pd{21-N*{iK?x6_(>dg34yo{`*KnL7D`laTJt}3XLIo6{!;N z*}wF5P{jyd=@HJ?5xaGD%}1HMSACi|#A^`?IZcMzYjnn}=kL5cGlseZ!WzgA&7ea9 zpwB6tj)!Lf$wPJiPro@{V#ClqSwhsdyb#&vw-8;C zVo_Y=h-z33wI@0eg0`cFJV0!a>JrI0QYg6Vj+3rvdU9)mXoy4SKUi$+_z2oA(+=jG zEg76q(WGmJ04_>Iq}VQ{_(Hyph}O;zhl#Jp1xBMGf#)ENLO`&|-ve&b*%O^bI;%*Dm?6XbY*Lhug#>!U) z#%MC_kGmWKHXAH8?x6PIzcD(uf>VDg2WY6^f8-SaXd3_jwbB31pPU1B|KD%A3uCvW=OKHWQC0ElD$J2SsB?PAtZZq$*t@iGA}Ee?8+`H%FGUBUDjon z&2yZ(@89?Ldj5sy>GisAxtzywe8&6p{*2>PsHXZ|Qerw{2!cqJ?8b;UBH})Ev zXEsy}67hj_vI=d|EZ{5Tu1N)daSOu%|3|B9!QXu6f;B^lDxKx5X$2HQ>T(%jtK>v9pOMrDIUWdxKm|8Xx*m4)R`<`oW&6slVs_rv`5CS{%|DyW5wSx>BO z8BOiAeH^QuYc4msN~WYBxuYhzHAd;=qR?h^c1@y>0S^LUDL_1W?Bv~9T{uvmb0OL9 z9=))w^V%&dJ-6CDEGN}SX(XWs6;WztRFlV<%O7eP1cc^KFN9X{^#*m9jCQq5t$q#?X|D`X`@fw zO@8cuK8uJp^YsvBriK7f$qt$9HMuJ9Wo_}b%T`ELJhQ3)#7{VD)_0t=mP3JnrJkQn zkx}0eea|gDGQ_|?wb7q!&n7TDsRKCik9nFMp0=kkx_jjsqLyPc1of0~Zw5@)38 zG3hXr6d+kGNLIO2lH(*ZsX<`cxr@Z|rI3w|FtVadCc}6qexESf7!MT-wi8%~4czpz zfB#T5DwNfM7i~~m7QL2HKi5mh6q%=Y1!~CvRF4!f^VT>t+cBlvsPabXO;mLMlvxjn z=06x+qX>msHh^yZ&LX_3#iqVGX+jRQRfI@07&CikJWX|*ackcOA=EXXq~WJOIAQja zZ$s+!I={`F_#bbzdsyRAAkgXH5SyaD^h9;P_T%@*1s?<@+`57+dI(tkoir{Uujy~m zV31IM86Xs)_S*qz(@sCq_Oo{gIdkju+Z+r5ms0hAQD(Sv!r?$K~tuW>VZN$+z1dSz>f#F^B((f;__^+5=I0~`@C zcE4w^$P&}}g)+Yf$Gz6!K^xh#sA5__!6Q~%NYfo0_|k3aXz)76*GMw8REDE_xPR6{ z-72shx?8`lpQV_vkV4%mT2Kq4-+Hy{%IcXwllvx#Ws#8iyuY7@z46J;{v8Z0q^Sfp za$gcB2;#2_W-DAhSYS|J!@mU^anlimi;aQ)@SwCo7`70m36APC>DUj>Nn@UU$xzed{bqaEo6Rd zU;+*Xj-2T7IP>|4eN8e)tw%0f@i>UwPeimHP%8-b>cC=}{0|&WJf|*a>&ZN%oMki9 zlp0f8JDz#q3j96gYMT638RAL5v)gNd{R5G%D{N9 zOE{r|3~<@0cQQTMJ{8Lq_OZyE#A-fN-`@L6nr%=DT7iUh_?Xo0~$ zrx6x^9kCX9=MthT2>Ac!`o5?4ao3z>A{&Z4;8{u75skmFPbeFNBmq8>^QuJjhtxEO zaF}gZ*uMpz@`6thCN-kpuu|97)4UYaVh9BE$WB-?PV zf-Ahcc{GF}y1lk?OP?96Q(7knj(|2n7KFe3W;D+w0Z%sL2_reBx&gAd91xxgE-LmN zkc+v@*IInzetw&^1ijG(q1MFTTWeU6_Aibf#p`wHptVTH5{UR`F(!8*KQoIBO0n)P z8N*PM%q8|U@TIeoLVuLBAc5W{Z*{}diP288{7VMVw_!nUi>)_X8r?Y1pNs=4EY?KE+Fl`U4PQa~>&<#z+shuW|UA#zrHZRiiUhJFoE}>^C4Jdp#&re7Zk9 zECr`MgSCWhdhp{rygm=C&xR4jMPm6o!9dzE&^h@g_aCn_rgq#o$i}Re5fU0W$y75U z^L?Ziho>oQ7eKDjG;cYsrVLdx%{)g4ed&{alc7lgS-F8!)WN`{5v_`YJ^|64@^f)# zu;m(m#FaRxdkp|&1ibA^xt`FRfAB0G+3|B=l8&SBYU*%Y#p3Uz58{DTt9%{ z^epyjRX{v}Yz?3_=jY4Iw!K$1LVVtOObp`djJ_nTzy_Sz(YtL;jiZF1q8=0tGa<*f zPzhl1VK=w-Hji`)4qnD87 z&rNyg)m0pw*9g8Aq-ewCmR~O+U8@)p0hJjEktyt^JnEX%l;GUQ>&rCCkj^Ur87e** zRuk7x6;2Us&}mQT&Rkn@uNo7O`8KeX`9FM8Qs2Z*hPQ^4A6OyY72m%)H@@+Mv9sZ9 zV$IYRN=OBv&FVUs_Wq7C^v-8U!ZK4v^v3BO3TOdzc1Q$<0=ih9FY&~8M{3zy89WXS zMCzx%k@ozgnyv~7P;k)GmN)O-Uv7+pIQbP3Ev7t~sUJ0@+4b7+44?>wyLa2{%xE%` z@MOJ!@_%N(Q(6x1s%O52aw=vJf?G#S_heq<$%n(8|MgJ!XOMxWM4Kd@J)nSuo_JfYxvYd%r~uis zIia!k;SH4}1}~kjz!Y;)QsN&S{{8?IR`d2>~SPHOyW-i9Q#uU)Eor$D&Odh1^3s!}QF68d_ z0^LHPZ`H7Fe_ceCDks?ghfjjF(dsnZA_@@6#zJRDXr}jl?{pAvs#;KWqka=-6FucT z)KAR7K;GEdJ_@up4#Pp0nw*rmj$eD#K?R~hUBlz+`zKBxA5uW=fW{|A;8L0_I=t#S zqTjnbgA${PKqph-%T9{Jax@M3Uc!lZwVYnjSC^Q38#sp%_c5B+Z{_x~+a&=!q#3`2 za8%>&?tB#zZ4Oo$tw`}TEkbutTf?A49lSHgt_)FyXG1m;aICE?M}Z(k2Hfon4dMr? zC;}O>fDFCdrYjIHip6Uoe6~j$;*3hLdP9Y(b^0bTsIMU=)*FLowbRd9VU>Hf-b&~_ z&#~Zg;;<#M(Ijrf2WSoeY@*vy`c19RAVP8b`=aNcFZr`?Iz>8IjR-A=4)1Se22EN{ zE%G|`d@$>28d&;WE`H1J`RqTU4VLm>Gj29_DXqd$ZQB%mZ$yTskN$V4 zeI*+Nv!~0{`0^wNBducs-rPdgU5lQ%t8=lPnGrt1j*<1@o7iO-a3({u^C#9FT1OsA z`uh56uK7s*(HVL(pFMq0px}UFy5AM9`*vtL`Tc@axK9>6DwZoEw^Cn;bcl3U=N_iC zFV6;v&+)#ZzuZ?B8K~#|)J5{BA=)ZK85eX_HcgJa%66s)m7;nSLPLOH9I!bRe?+1? zZtG6ioxH9Zd|hST{%QTrtbo1JTLXf>jzfH z1t#5rQXkeLb`z8688fQ}Q4I#VaK~qpqN<_cLX%D}gI$WjkMuETX7n?6@Eu_Nk+I5c zoyQ$5%Be0 z{(xOE?t-P2E&`PeF?;l~qshsnD2&$69DY2`zUe-ip5Em5BYc*$_PPL#9yQ$OrQB2& z+j{Sr!-jN_d$$<4AA!X`IOsN5?#}U*}d!>8>Cm> zb2?;B+fsbWAibn?yu{d((m4cM?r<>2A}T-bod_&-R1>Gm#6?+>D+;);UB1n_R>Ywi zKkS|Ef9p=2v$@{7?~SFc%+a5wzbhkfIa(!1N^HL++44fQXt^a6Y)o{ux^5l%22(>sgf&1EdZD%fA+uS<3 zEV^{2;r4V98|SN0|7#M5lXV@hgzZBd2Fbt_ zy_u_fO@Bzn2jV#MjieL&r7#7a8Ehd)!z)5ZtOjv-vO5Owk}Q+0XcZimmyBNfSfjZ+ zDleQRmT!%dkIv8p+!Ey^VG$R9$ymw-1ggr03L<8FZ#sBfrfWVhvHysj_B=Q$|F-^G z>9(=AcZ$n)g;QrMp?Gffl+>w>z0a?+^um7-DPK`^1^?L59U?{I2neJcTP zc>C0@$|t&sGxac@a27LY<9NhynUeo+;smk&*?ZvH7J{p~ytOrC)iJ!;$^21G`Y|Yj z9UE^oS#rz!NSt2Z($|I~WNjGM8syMB6jct&uPtP~6p5SIcOPUVc%jyw9AoHM8KVi4k>kD-z0V@`cv9Ygbnl_|pK-@yX44h& zFl=EC>uek4ED5NM7++n%$rE|5H6h*jU~BvtBQoT!*=gaLta5cZ9C+$!SI@kb+NfRb?t>2Q}AWFci&fhajos!r)`||c2TRDwu94-DO2*Yj6Q_`UH6MWkB+X$x^NPsw8gjn z*_T&~xic&U;v)lg$MselE|Q5mcRTxqh0Yb34GEef%hNoGYZ)T7Y3q@B&F~%sO1wh* znY1Wpi6~AND0w;4VS8nG*r+8bxH*hno-{o!T8hPs{P?TWsiYD;5hW^gDF#Qj2}ra| zFTl%}DDNg!!Bso6IVW1X!!Z8Dw!Z+jrq9rdsO57_8eOX+kp9`jAkNhFAPYJBq&w84 z(pQ~&Qua5`;Yr{nwr4jkQs$*`xXHyIuA!Qfaw(nKF#$)`UpvuC8&a|Q$+|qw#SqJ; zB{kE)(X`1i^Yv7RLg=$@etv+Im3qS+is33NyT?FP?t< zo#gZ?4)sKQbz&{uLkig(ukcgGSQNUqCy>`(OnO5f7s($P4xtT>3^x8{$>`&PTy z`taR)sHYOeu#1AVuMRPE0N|K6=py?yQNG6hO2ir=S(~qNKQU$|dFt%*Ove=?g3r@E zVaw7j@!HTfsD)JK-~;O4cHk-N^mqi&WQv}3tobYV-`Hs8I~w`6*QtM9i?_PFGaCu#Uyz-VB{d` zYnF3F>W<^r^|QL8S#4#V&KD~ zoq!uQe|)v-=**9~i7)i2=d{1zU1BH_j3I*e>dKYxe#^KL&!*+SCq=a?wSZ#rhRc9G z8Jg7VTK-Z;okD+iq?#`An+v#?bzJ)_dM#?EBOo46(QWT@uY6%xfaimcvc!-jsBMTH z|9tgKr|RDL6Zqa`oOJwm9J-*lQMi7$jBw5)jUOL(n|zaUb7>rw(v%NPj!Plo|!=``;5BZ)vRi8PusC??{( zRZQIN@JEgC7fuA|b2&?Jtvjx0bC&xsMht7CzxFl@)}LX>It`T*l5m|69l&i=BZymb z!`htrrIV~j3pq}2**NPnOTw%2G)+w&%svJ}WSsBwwjH2EeXlgU2G)b0sQVdg>t;_L zfYP*&Z`;CwjlF@5-_bvQXu2mwpLnF5o{6d1I#bR{`}il44{T)GebaguYTxZQV`I|1 zUJXL+$uy?wOB`Bd{b;B9+pnSp*G)5PWnw7D5?J`&CG?H*dd7&=T-o8{#||a2@?xc) ze&UMY$FN~-XF{DKsJfT4IOZ(1(NFywr~BLt?x$0g$KkXr0prN02#c9A2XB8^ZQW15 zbFnbnO62iqxerT5til1kDDU(QeAEC8N7sk>@kKpLqpNda&L*$QqjF5nM`44ItU}^;k zIEUdtbd^>Dl{-yIChSBL!JVkYKE%+hCU6%_CTZihEX}wQI$P!{Nj4NQFhQE(3(5Y5f%isA>d$L= zG0`ms2%U1i=^J`wVp#*uuTTLCtmEv!bJ;gvGi=-GTJC{v9Z4DeGAN`K3oN`KkoP(4 z_J4c61d8QdImMzlI?p{Yl4XHq@PMr;-LxxD>!6tcoyy4C__`d*THVMS^1IKTEJn zKy0?)5fwC)PR?EdAd1L_1Y&TJId}3q!*ew+ML&x&15p8%q5|nHom;9so2YC&Y~|Vh z$^mse-fl}~!$<9lzzK)Mx%9v&}`WtlU=OZ$d(aH$U zkL$LA8pI2mn~Co={@oiB+PYs#rIr9eNG7lvx`BOztuX!X;2rZH{9voa-Y`C{gwGwV z53m2_fZ(0)f8O6EW>*1lAOljjaKcq1z_Ny8_$1(F5a}(bOXdl0J=!L7H5mik^xeb% zhAOguASOIYqX!n30UU_ZN=cqI2b+J)w@d|(+yzz}LqrUgd;vKr;WMj|Mf`uC4#eQ* zx3O?R=Myr>Jb`_K5|G=g-+gVC+7OaK5n*mlD4 zWS$>K$78VfV(WXe|M>l6WIu}vl`Zb9qz0l%vPNn>_FvAONNm3YPWe!ktqLIicL%uY zsiW$iTXt}&|0^BU;M>;yk5p=D=#c-H&OjlmL3qNgE#QO$p?|}nks~13-U>D)%!tVU zo5@-rGD;3)utEHsF8CafgdV^n$b|wepWBH3zL(L$`E@PibDrj<)r=_r|9+bDD1I+g zovWYk$^Ebs@H3;#$VgxeDPRoL-Oo=nA{k+Ofss8JDPBsW7=oAAfy;*T^w|PMzr;!i zva1HV3;H}&OOO|{@0q>!zpd}~h7`iMB!E49!S8s?HIAy=a>(4*1egr~^WtV#I~Z6Q z5$jBS4|RG03^H3^h4^nhEA5cPtOHojDRaIaD{(Cfq*cky$CA9D_<_@*``+OgbFgzV zi~voyA@NyG;FbrI7R6K$TrJ1~t)le74LbT5wi>HY73-xWd9e~7@k5}1Fkq5?0^v?N zu4Gv`t*g17g3Br2(aO|Jr*qVGPF_O};TCe|5l^P9cQ z_4f{P{>e(4s2o7Y0+`H0$iUvHhd`_MK7RHfDUJcs#g%rh+W1FQ2`tMc5(GG^#swz% z@MeVkF09>;bM2n@CwNv+bw4t9DFN8~ciAmiWgOkxZt`k?d$I66@UwGQgYbC<7nvXk zK$J(+VKk!E|HexmFdm!}ryVoHHdM0c|76nN%9GW-zY)TQ4^0GSL#QA0AIqEdA*j0- zb&0dVp|8V`3z}Pgaj*<3zfQC1*wVjZqdpzAt*ohP3uL|65;|uks2W`FKHqPSsBInnh~*c49N9CEetGb7Jk(HbQQjNeU(^yKGDk(~8{QKAWlL z6`uO-DSRhR=Swk}3MpA~(~qkp*FSh*e$a6XlM1^twhc|r@p?!n`aMX2fPGh(^tgU2 z2?+;AhUgk3{#J1rE4g|aeyyjHO}T-;fxjbWXC>q%S(GGSPv!6+9#X=H3{^SCjANe0 zUfw8X+~K?*YrDTp0S3`>u`?F3quJlcRZo*P$pAG?xw@`3;m)Xce8t4gdC)7zWwu7 zKLTJDlr_*;y`&xsyhjFo*#N)NxwJRGSVA_dfkdPcBMnOYF;;I%2|urLbK~<;y?+}FyHmrOW8#J ztB)@zl`6kjG6Q`=Nh1>A)emBtnV<_`tu$B*o1^WoIRN~iv0Fg191dXmaPq%rZ|}dY zzZ=1O<@w~S9Q9YbT^xhNaqs?=z6GGgJUn!{&p7k-cZkzi=zT`qb+0(!7$)GDmS?#M z+YhO4F@GUn{_=}X?-?|&03MD60t{{9apZ^6L?lUGlE%``g}91%2lDi!;Ui)wflxQZ zNb%~gk5>{!ai~F10w`=C^F43p_e#ykJ-)nzyIJp*;-CXyDXZ_BD1p51tR0DJ&+Vnq zU%iR9rHjO)(RiFlu#HlNZ$F(E{1XsKS73qGf6qUU^cTFu9W6gVNd`Fs?{{~_lNqu` z6GfF0CKzbQP2bhEUPZ{Z0+ZdW{Efc7o&0mm8_>;7I9pGx0yR!7=o3o`A$(w}?yixb zkuJ*@ma7P>k*Ov8N}g3(OI2wOa9|gBQGk;b7?L@ks8>=MxCLB2K<2buc^UM4uth3< zL+95NSAZqONi|%xRce_umArhFcEg<%#IH8WCR%};$oYG~VCw3)pPnh#+Go#wA%vjo zVEO@hmYw^yqfwP>L5r;{mhF62WKepe3#wV!PF~s#iKSTK>N?6_k=%mND8NaG8{aa( z#~|(`VZ!ZOU_0HO|G}Yz@&&P3*==cVvnprDE-qz}`wvejzeX=KuLg<{^x#^kdNdLN zbptm;o5r<_)k=<+MwcjA{~ov?C{PWoM48Sgs4brkBl{+}j^ezoi0JPH2>hmyZxjcj z46Z!JltFw9E7`G$v5?Tg>iJpVbtM5S<)sn41pC^2iq~EtXT3ffN(fcohBpvb?5`x! zI6qwuKK)2?3yrU>0;uK5Yc|9-$idwuzYrGcKC#8U@nkk4z+U|$Kvg0{Y4YZ|s`Rj` z&3(X2OW%Ic!3So71FIwnLK-dXzxo zpf1ec$oro9*-B5@Sz+-u3~>Mr8ytX5Low3JwD&4+Q)VW_VPUU=DLGpAqXML$0D@*; za*R_MwFsYPjlM8n_b{C_!jEAVhUoDWPmeCgG)O zd>aaIh&w@;Y=*bXd!M*k8O+6x$kdS1}H`Zv^NX%+jI zt})V(4=`*Ib2K6c{-oy@-Fe!m1+O!rSF}}jEDJ8K6rNb?V@J!PJANR~en)PuAPtqK zX~~PLc&c(Gn~w%+hWy5ilJ%t1!JEZG>td<-Qe;Rk`Kg%% ztA!l4d1JqiULApS)gtXCQK%q?Bk?s9auJtapiL$~JC>=PK)LSjhWN zZO^0kEVZ!yJanpp0-t=|Rl1WM7M<>xRAfdr(NE`)P`g9l<|1&QZt3ME6)qFxof!es z=@)U#Pbp_)qC+GesQA@Xb~hGGg(qkSDELaTBnlO>jX9AeDzx3_$~#RMtTZ$bS{%*z zY&Wr#Z?5o{fe`>`-xviZyfrIB`}y!&@$aX_T(XvPsGO(`Zhf|{=n-xv@1fu;&T?p{ z*#2<3FT=Bc;%GRArw6P9I=&@CVw3^yvn1JvxbpJwIWPRtL6(%H$M*AGZ>_|c3h$j* zT`E5Txfww0hBOzp5bM~~AdBBxrXC$KTtnpgdZYa~VQ>X`$lh$Tmwk(cue@{{xvYZF zkhB@_5k1eCuyf)9EhYR&j5|U#vCkWZ2U2cb*iJ6+|5*DG?L2Atbn@bQ#B6z+!R0%c zdl9+S6)@B9r(tPXQQ062aqlVuE|hPyOiT8c3abw@*8pb^_!gV&zCah(X3xEdYuxQl z6o#)H(b(LCGR|LZuGTx*I977l-+PK;dai4|QG;)-$Fx>ejK`rWe>lk#dWi zUmagX?}a!$yg%a|qisk&JoZc=MfoYY>Wi|lL_CR^SKRL6Ki~bbxY2VHXfAD?jt}43 zX;M)s0#@^l7jfi|AIc-&!Z=)BD2vwt_k_v%M=m(9hloYR(wWG)Czhfm%Uc4bskNp` znfgAEapk=hGq!H2_f(*#BhmzHfxfYg6#Wz8q#(SgNxZh6y33t?IAgx?R9VGVE7nvK z`gc&QNG*E<0xYD>ogn-`hWr99H40wv^a$rB&^4;nvE6;_CUh$Fg5lLXHaX1{ zS$aU=b052h4G%drsnh;W9C1)%)>vcqjgP;)fu}QIJbhL!X&KkRC zXo#AuU`a8Gu#X6NO*j8~tvHD?S>MOr;Oa<0Fk`0m4H-d{+ zp<|RCVJ{U5kgwhu2_i`qI+#R~XNH7i@bvJ}uZHd#B$j@yED>R$>F5{v`R(1~hRhc+ z+AEQZ4q{^mraV)s%J1rY-U+>|CG=x)9y`tEMACZEPuotyx6tSX+61=Jk8`bT~{(}op-EHqCHYI!zxXrBhR4u*IdQCYjm zHP`LD0~G}vV9pu7ni)h|`VOg`%VN#7Rd$pIZ;M`EZoJP)k{C54)hK{jEe*}0X7Ib; zM8=)!%0z|#?a}IA>FuRB`~I=!7~A`UQIh`QB>JvVpc{zqrEL#FA1-ni=<-}BdaAK2?`bv zM!ZR#P^D@_Udm-s1(!<-^bYLBtj&I>JBBqU%z4$E+uZij#yyW3Ha@>X__kVv9@VDxJN|7hE$`G5 zL%YeVA6?#mFUt1oG4hcrZn*zf1|;Xtr!N?`IR(Uxo~ySW>uAMLb7T<9+|g9o178&D>E?SVONtf#Jz#L>49`x0a;A zN9X_P?m(uk+3qMIqzK;3gKQ$;JpH#=vmpgF%x$lWYz|VKf7-foOOV20=J$wdKS3=8 z@QrcLNRWj_1eF*B-G|$_j_e0`h#UH4shI>*zEib0lc(SzPPOrzfp=%@w8G?pDM~e}6&s31c|7TMPDt>6X%X+f4 zXv#z)&-IbYa#(`4nTqWl6|Tvi^3#dtI+na@o;;yu$FXYPO z{^Y;UaQL*CyJJq;RdF>__FXqGQ|wE9&+4CC%wSK{jUHQB+gXvDcEsD_;&$=h6BF@k z;><&tf-pZ`mC?++Vz@4sZ**RMbm+(GIj$w={;9RFC}JDS@f!Fv`1a4yZmv)4!`cY1J(O!S8>co5md^YHt;@=~@FAJO5Dl}BE)=d>q4$M}%uC#s>g z>w_{Mz#7Jj%&z!?o!YQO zn;dYhEpGf^hM`#o6zEx}}_cL|1Vl^VGlcubEDu~=sx!^T! z_)}~7l5&&$Dp{HOwRAwN*M-1EfMRJ>N3)Z0g7)_Pk?DolzT=RGbmZYFl8Cj4EXTT} z@8H#_I~opS?|SUCE(ndrg*?>m3DCV*dTD9qTl46HdM3r`MZxAj81p`Fg>wOa{G)X7 z{^)C~aUj-Lk(&KI_mP%;!^;c)RLl8OpAt34aH^9_2~mO9gF!1|rr;}2(ZUBeP=bnJ z+Wp0|I3Op@YCM?Ssq`L*e$XVKvJL3&SQ8337e8&DSEBwM4xww#UvMbe`;|C&jP#zC zx(;@lSU7cS?+@MXz3f?LXE$C_<}f-o)fb?DkpXY)>YY~#-Lc)i(y)LwxjdT)eMSX(Gu`bB234Qc+C3Tf$9 z1{#T0`Vo0-1yhQrA=hC@S|GkW?Fdz~ul>}Q9B&T)f8Ub z!s@mdUnOreNPOdo0}FJctI}Taq93K{LS7f>6&$?ESdi>Pd0Hox=9UV+o=LNLJrYGi zhl;S40xgdng%#Su3f61m6hT#Dzu@?AtI}Lo;cNM8HHoT|7K|w5BdCRkLa^ia*XN&I z1L^Q3+h(o!0?O3LK)x1BthHIwg&;OG^xRFOQ@^Z`ooko_%dYQ z+X2UDA?|0lo`c9(xRq9;0|S8M5C9-3<`V`7CuHh=qb2{7$bRDmS|sl~ExE@?cVI70 z^N)sFnTy}qm*`ILpxkU?&PlU zH7sj~V*B}{s*Gm>FDudf+Y;qJCqnj*IHzv}t2>H-vETW-olpH+^1d6TddjnwMTAfT z{im0$i#b^QUw^J41PvJ1*b#fV%w)<0E0Q&@`X-C|UQQcQa^`>nD#ZxgL3bZoE`8tG zx+&BB8@q7hU~MFBqHl1;#MFn8k7t5OxTg|yQLhK~TVL)xwVDd!?9)EG9Xq2!o=GBh zB6(PR5%%pKR8=?J?5I*$EG%ZI`Du)%#^Q>vN}>IMv1aP-dKX7@Ht<;q&r;@ISQm!q zf|b$05H-1~hpE)8OO{(E2}Jb@#OHwq!C`j8t2~E@km)CC2}KDS>Xc0Yt44-DGZ#n) znvM?odUv>}YOwU&eteK7&81s-U5+;eWL_o~BpoRH?hRR*To!cp!c=`EK2VV6CO#xS zwKf^=aK!XHP@z5i5YUVH#FDuSSNuvMSC+z``r=L+q;m2)$V*RAf8mHeGTzNbPc=(5 zG3U7k_XW=!eK_;JrJ?{ARw^&HyYhGno=cN*wO(^bd~=uQik-nv7X(T>+A&?LXE8bgHq&UtHd2*O}!G#|Y=3N(FMwoxOu<2{_ zF28g@f*2`@oT32;RYlOsDuce^b@_O`bc6lqHjz6O(P_@4c>jLQ z30c01g6W4Rt+HX38xO0%4M00+jXjTKSF|Vg-m5aioUpUDXL)kJ+-q7IgAj~6nHO?xw)6an5l zcQHR!-pt*K6IvC1C@Rh0PKWO(`E2{h?ka0&b9@IG=0}A4FE=a>gpx-<38tJj3iIrn znd7SUr*f<;kuK|-Z5xG(xiqn%|733aQpFD3YPRm`#I&cmyxv-Epoujj3ivdTIrlom zKEv=<>)A+!OrK!J(wX(O=At5D^0IP!AR8<{=ZAX&)Ula}v$oO@o^+RQR|975DJ)XB zPn-p5=$y=ChIE-B&i)uGELt;Wz6nvgeqxV1RNQf7yE{X9yj;^vm}s3gS18k$)w?wz zra#2jP+|gRr$FDhaJ*}EheqLDYIZ-7kIXka?`U`y7fmQ97yh)SzQ8D!M50_D^$AmV z=_RYl26yOD(}}6V+ir{}%{%kWak09Hem=Dtcl5nsJ_y?WZ1ED>biPJFf0z7VC9U{& zCZ7bxz4t?5NW&hkfWr`w%_vVqp~p;z#s&71L1 zP@q$U$M=)?;fm@FF}sxC1Pl)rSX%Wa+6OEcGR0fAyq4Xp286U@(NQ&qO#yMIx(9a6 zgf_G*UnhgbmT{o%P8g)hmWB1%2etyw?_GYi=!2P3!E{S7tmW}$=ZZ?JhSoo8ofZ?h z>0TPmc3c~x^(0)9Vn$w}32FaCyOtznk6(frl0_tg5o(`Dc4wI4i=686tGO!*8j2f! zSQ7F#`+*Dhi8?!F+@_U|i zRjo=L!W5#W=yTvGIu@sWV% zvYAMT;JxXq880(dJf^Np%WKXh8~&P^S;H7V7;QT2n*K4AjiT^fRj@gYt6Ncq<3&E47f`=6TqgpMZygXdhX zu>^#5l@%4W8-?owXEw=hM(27lHUFYNdm<6zp2Z${j)ax~?9Khi)WB10TJNvm5MT1x zfTE&_{p{BHio&TT0fEw@r^~c&kHD|>tVui(;CyC7TiGCjfC7(YE+HVvqTc6F+$8$? zE5rj<>;pgUvJ*@=Ke52iuNs#+=UZ%XP`@mc5Rkb@e=})FNQg_>FV15^d`1W<0ECAB zpzi?1p^GUaWfb6w=mlU!N%c8~DS86tIUrG7@3rpcOP0lAc#wcG74U@<-Nw?*%e?`Y zdzrT-MSkF3{DgqKvH+!Dy!qgg;WN=!3&llG+r&=4aRv>&9pHNhrdyB0&NsDGYQ+!A zwI+<6L(pepTQ>4iX7*BxFHYb`vM@?;{Edll7xh)!v9_lXz*;QMt<2j4bGK+>xr577 z$QmA+AJChrq`cuxoWw7ksb!7-yJW!dm&Dtbb5)y@PjE%0146sp-tM(%S!&vQS_ghX zZ8V}g+r;hy6*RuD(u~=X&)t{ znhdV_`+OE%-bTg#cVG5pGYQc*SLp@rlQLwEjj(LLa(Tw*z469Kva=@FMAOCed42x{ zh}r11OH>X7MU%1dDbAlIG_9w*JhS91ORosr^uZWgF74YZSo^*B;p^I4y3P=tK3K88 zl4gYb*nCyFc}J-b`{K>f6=>5NrcaK2e9{`4EF(H%hcY3gXjoVJpravDLRufUag8a( zy=hRqOmE~yLD5ro;aW_!>lAK2RUP~~NGx?wfv8WWa7n$Y$E8YTR=PqP9Bh=DEKz+vPzYy@& z{ceO654QfZVL83;?#y05n9NR<%dCC2zv}isJ~-~S3NyKU4A~ZnBF7{!dj8B_#rqFviK6?$ zSmZE<{+Tq*I>+lWCl;|>C2fm(uZ!i&j-(WE&P#?nSz`A-UXEp7M7PLrIVKR^3%`3> zHL_L6N|sn1twAKMt6OvNd6c4pe+LhZj;`Ak^Q}*oi`Y-L?178k^s3LUo^KNLGcyMJ znh-yr6Ulji*i-Vl?7K#G;kXEEw=lQU!!Jr}`K~(W-sa;9b2{_IuEK}!LY_z6^_MMa z^!&vpTi>r>Pn!Z^KfN#_fZ@~<^A*<@(^piam!y?XKY?t4$+ae~%()N$ zOyX1+`3gL*7Z@`9aZC5#8Y_>M_^EAXTX5wb?pU6g!q)9(toB4=vGIC=JY|%A86NiIB{3VrRWc&QyB9tK&l` zd>ryvBg_w>9QQ{nDWLPA0-q0Vd+LQ| zTWnf!rkJz~`GE_%^RA_=C~fSpUFO$APmQ4Ym~!poYYwdoKDl#F;++!YuPq zU1Mig4{yg2W~Kq~QpA!el^tnqc(%P?uj~C#aUP#7C=&c6ia()6RvQ^U-K)`kO35Q< zD>#82R4xI>)~A%SbS4s*6;%0~hkHLG=q7?k`%c02X**o@sGKU#K1O8)_&5xyGb4Z0wP|4OqvAps;SeSXkSLZ2F@@U-YRitv6p zqj5gH`GG~?2Ko1)4|VK>g1i?)aPe@CN300C!%F<;Sh(`7=mk zc1fvhz)->8);Gze%=_n2es;5`#aEZx1B{o4K#l7B2^4Lbi`k_wMP*euhM_)aBA06B*|ykyH8^tLITsEZf6kw7Z33|Mmu&JY%95&|B!P zNh=<+V=2G0w{DG#VV-{3;aasTi7?HKT$0>klGzdghzSj8pslYWQLnl{Q%$n`Zwr7_ zX*Ivb!b*PdXvumitc$7l!~BEUlLsTQOlkC_3{0h^cu6n$H6mF$_VF?Aoq7!_dKV)0c64EL&bs|kF4N6%* zSEw-`0-_##6A-1ou<~8w>xr8TTq!>MTt*1RWN(!gsoK^hrh?q~Q>KnKHaMij`3l}{ z6lkiRu`py>opC+Y)djJ+^8=A=F>vjB#mLfy1|LIekNV{zy6~&}gf?qg}&<24TAV+}HFQ9kmU>Z7bB{Syw zrKqDO^k7ho8^a0Ct*NTs{CZI|D^1{#MjbK z*dI8X)^l)+W4cNnlxGX(f_Khqoqo7bf&YlZkVn=Ez5;*W)dFGt^HF`^#ZUZV!=NCF z2IUGwHp%7N$r&X21{AoEKU^cBo29oH0ZVo(R1@G4KS%{!{R9Dv^V?su2 zKZ-R8Z2a#J++PyRW!W6plK$^A+%y-70WU-8Dr9B=_NUUXVi=>ENVpV}ECb6|i;A8G zReU350RQ-x`32A=K%dB7U=m+!R}o2Hkx&B1U4WnchY4>+N7u@>^hNOCo_)FtA>aSg z-kbkJ^~UexmXKY@nr%{uAxq34`xZipWGxbs(HLv?DEpSRjO>kFvNd*PkFkX?*%{gQ zefiv8@9+1A&!6ylJl^wz#&OP>Ip^H>^Lah5>w4ZX0r0AF@g+531Zl{($451}@3T?m=r$gW@t1dq0ZnZ z{Zo7F?YsAtlkDIa=JyvjM1Lb_TCTP9gt^vaD&kU9sJW2e>W4y7q5uga96TEArcYnt zc;ztnq_P?!L0!+5;s5t(t~ozQ^BU&t09js?aYXVz;Ul3PriYG-VOp~kTbbdPB>U6v z@mjyC)dV*lAMzAHRU$DC*O4s6!l}8`P?3rktUD~wI?4^RkN3fYxVVHVimCe<&DEhD z{q$?e&KCTAtdd^_aK@MCvr*B1>HddbASx)}2LNW)!HBu zo9Ts3jgBB8VFBR1xN@R1E_AQjocEk!?bW#B(i@RCe44Y?1tB(7YL|$f5}k5g-10gJ zulK%W%>|`6ESVh-Q2_Cdn;z1Kd&Kj3kVfJB_ zkyZI7WQ(sa9exB$7Ls#s$bNHVekl@__|0a-%uV4D8nUY5Axyx37>0P6-2og3Sx86C zB`>Q~aTlE>X%9iHE&dlYlLcD8-1X1NgK*+^IBTz7Gg6H$T*vq3L6Tu-8$ z40Ty`%3qnV17Lw=p%!GEL-jo2fK4{OU-(q}{J`lRfwTk4lx|iMX@O8Yf!`HueR2#d zjcWBG9Q(_evKa_w7zDU-U5mJP-cX*-c97F3#Z53(`$FK?I6s>kcsj5?egu=TYr`^( zo6WBJqG_S`KUg=bZ2hGTd`G>F9ez2vV9DP2S!&FD89TosJ)#JE!qE%Wx~qL`!uqH>1xjh$D=omI=>baf<^@pVLe)T+JJxQllIl`;VEZ*&lwzWGs`kY*v=Iw(^b0!V2jM?n1$Cnr-` zK|MEjP_eqKQ~2wnJh7MS*NuVG0bk8$iOPfpKF2E`>z*4VbTY-Zzw$-PnP%iUr45Zl zal7mps;JeMe9}ezN^8VfjxDgHoB0$)=#GUQ?fm>R9J|VvD;p$0{zhC<}V)fs&7bfmv~U+spAq84R5!I&6qOdVF!rCHV48``5Gkae#Q=(?x3H_3ub z(iY9GJaL&QuQh%@ut0YM_mHCZTnH3al|nF_^CvTF5@xE~Ep&RFK?Fa7_k-6I7%Pz! zW(7|Lw?#ciF>_XK0Y{cU_5vXI?e33MZov^Jm37v%B;l9ZP&(JWN8dy-#a~H5394@Zx+y$BcwZ zk+MDdpc+^1!HfsD*3*~5PE+Mlx0xK_C7mkE>e3%px+C{j-cMEzEyFq}qAxuid!VNA z->w-!qzQ|KC`9u!qVBmq^Zitc_lr2V%=GPy4j;8lqAo6Uev4W1Q!&3!#i7?u8X=JE z2|JNP{lD@@e>l!3Q@xRvM=)oqh;3I({mrn7!7^v6??%J>CF81M4TFs~VKTx5`p>$g zH(eIBW{SzS%~Q>^5ne?-_338TRao&E{Gomqp0R7V9b3z4cV5G#Q|BgTQVOD8fSoK% z+!Fprr`B_7DVH>Lf@+qj)9%Yp%Q5wsq*AZ*;(`K0G*$%Sy3#sY2f>-1SrDy3vSE*L z*dgJWYsWB5;OyMhOHCTwP9*f*F_3Ta*Q*mI7KRnt^5-N|8g|R1#nMP7e?h@HuXM_J z&Ce7yY`Bj-Te!8c+a`SZVrca9ijmS8j0~)u{zV^hg2yH!A8R~1i|_DT?Y%MdE>r|} zuShj)uw8a{1d)fswU4;w5$6&50CJBr>z+#rI~Oe^3vwP{@o{fM{lX$nD{BqEH!d)i zFnBDZQwKf-st|8%5S^qe-Shu)H}}`$!DMSfWpMWTpKelg^1DBu?rr`QI1RE!CpVC8 zv>Kp2AQH3;1YNZ=8u8fIxG4LcfahMWtoC2`?lXrc(pRWcml?V8Xd|8+eG79Z`5?2jHx%REO=!WX~&UNG%|LIPRScj;M; zKb-M($*fWc?9bHgAYb;1J~bu=7>=HwWp(sYKgW1Wko_(O*GnUss)j_U=R`Bxbw%U) z+p%E`cA>t*AB~7|Ix)hY%qx4+VmWX0B2$ znMYiz$4lt-Eg)=YKa*Brzl2}HzG#xl#sYff;SY!vx%tE&_RoLbM>U1 zgtvyHK}8RHfEKr7Svj3LjOE3FazQ_QGeP*J=2{?(vo(<1TZI(4KApRGcPP@7Un|Az zL$L&p*9+xu_!%1~{)xSmPD@|I28tLQR>xF2A%L9>R*f9O-*QOX`YW2A(V)&DKSDW+ z*Q$j+jHJWy54kI!t+#P(=sk3sdxL!0!+ba;_X9vv*&%YluyOqT7U^m|wAmL%JNF3@ zBLsY2deV+^)vRk5=`)Ec-f?5??j{9!dy+qEsQKd;x;C-T<#Z=@U-I|Ib|Vx{FQ3>g zgvr4$(aR%E{tKENWE@s(1iizv%y`ndL{)vPZSr^MOMai`)6_V;1pSHK+CwqXapCab z3OelTX~#95e&MrN)d!a>?>2d{#!fg=fI;JHt9zZYd?-6K^D6Q*z9=pD0`$wtbN9Y4!`zsG!Uoe|EqC6NED#Z+`OUTim(pQGUHD}DVzC$5B zB4>o^(32A6ndd3d4S;uX4hHSoLEZIvMM`g`x1;_j>4HZg*7inCxd4mCEdE~Y>5G2&qfJvAV{Sp_r+rc^ zw;~R6iX;Rp85B zNPm@iy-*m;(Wjvm6IRln1=Y&p%f-3vY*xIB+Tp=(J3^D_E-wvq)PGh@)uDq5<0|KQ zE04Yu?UI789<=Q~PBZi9Uif>=`+n{wiQcu29gFaRdJ&%Sj|%Pf5DL2C<$1QG9e zULFxmd-;@2;`@kZTZ6!Fuf8rQoF=1GM=_m!_W>~#*=+|*+^dSu8{|0>8(e)vZ{%ZP zA+HsBO7rNRBOK=}F+Ddz+SY!V#B4uwrGm&^JU4sheS~!CiEq|-p}Ts{60tDHnVcX} zwoGxTm$kfxi_R0|OWFmXTU4218*HVB^ZIl!{M)8dGeN3t``g*?w z|H#r|-J>I?|E{2kBPuYr_4zc@48?qD8t47cu{6fQcW+0PW_}-804CxXE~Pg9qOvEA zo*$RrPa!zgejWt=F@2Y=aWVPg4WDn(Z>B1+>xN7A`!YfX^sW>`$^QAr?70U%9)6*J zAXJ#n+_1EW&Nd*rG&gBAY$EmBI#urKDVM)U6}ED**w)pBuPt1$VSP)e>2Wgt9PCF$ z#^x$ucO9acJLi1!i6C7S_qW^31luND$B#erH8fW-Wde$(?Y`>N6l$4wQobgrijkgu z_R4fx^OdxrXHiM()lUjHZxAbZFqQR(j*2W`CcyfIJ#o5i)B4%dMc;wk#on7RY}Lb) z2f8Qp*slZ1r9i59qhG~A9BW8dzv&c^sBD`jz29Y$>dm#dEY_mc{Fi=Ck?e%Yc;;Hf z#80O1RY8?`^sL|%`n?+j;xFX;*I4Z(0nhhLp8Com<3aB=_2+1p@oS2{+jhZx&q(jDU-n-D zC@}6e$aJjpwUm#<&X^ie&TWf?kz#sb;1O$g3C=qQ=^?FQ?oOA$yGVQ|(^BXv*ssl<4ayDwjhnX!x__c8RuK@e9TQ~sc#_k}{t`^D0m z7I_?fZIL8-8?-i|m^jt}(S`CsPiq4sqg6SZ#>lIbE%ayZMn-A%`mP|NDw@qW+i<}* zxk{p9P&o_)^D)Q}g$;5dv_tW%vjclkDtIs=ntMJHX*qB&dMlE3K+oBFpnPNIAiN>hMc~w31XA9^#c;v3=|Bd2)-_ zN-a%o_rhEu5W{K0Y0;R;P7Z3vybMDu-1MDC9X<${OsJK13_9vbTCIo!3j@YDUhf z*$I|oqnGO3LAYp=>?D+i`ny1#Zk%N1Jc#IkW%D1Hzs1X6A!x1i#CkfS<#?8TZFmT7 z#K<+@NR}BIX^VlzBNwlA)4TWxZ&d=-fz#KTh?MHjj;Qvzq!pK6dfXF#?dKF_$XdL1 z2m{(^o>9gtU{)l%xh655g90?fEXF?Lg(tj~!@h&9wm&iK(CGZLOQd}89wi%K;GFCG z>5YgyuCikN#EIgzCpSGWE<04$QgU%^m2E4gLSNR#{Zgs=97eDhPxm}lm7cT{YIfz& zhRA7cg3wpXNAuZtGSAg8{1Qmab@kchjB&j;SSiscjM@X25X3m=BR%TqZ7I)*!)+`S zhC8}isF7Z!3Iu=F=9*Y{>e95y0qP8sSPw+Lw-e$Yc0NH>M>Jd)jp97lHtTGC+bd!T zSmCBat~A@s*0+-rtD@gcHpX{$-p-ylZQz$PoT;O>)%BH66lOTf_Dgnv!vI9%St}HY zc28z*74~>y3Okq8;p~KH#?DK5BHoN3@>@v~ffW$&As<`cQm_UHe^uR|l3S^V?UT8g zoJ)F&g5PH#f$8dB(yC<}SpEky)#dwfN!f4^&izqwTnR2edwEdAElA*PYFM{0h|3|IkjKZR;t4xGne^)ipW>2KgDpe&;=8s7=5Uaa`IWBrhl4Oq;8nO4!oM!6R(yxZ5_ z2(2a%7*W3r#_*HjWMtLY#;ep+y-?5tmx4u^=u^+S*>m+Fo{AGf@LfZW^8h=$hP1Q;|6qbqm%+(`)K; z;jplHSWg?=Z+ZqDkSjl?RjVc7bOp(X>9KD1uR6R05>2niYi)m7B3_=q%aTer;jW?( ze;0nD!79I0oeZs4F`*1x=yyQ;d)gkw<4Fvk>oXN(B!Yk6^R>+A_GyVExwJTS5`G}C zKTtydHEweMdWrhn!!99{Yrc_khrVKyWii`dzQX9YjvIdEwhBSM`SIf7&LeZtBkolS zxP?HNCZk9Atq9H^Z|LfGoK%XAtp&03Wzzf1cK4jt#?HrSZdapmwk!Cp3HV6g+lzS* zzz%CBvLW7G@!ycngxp?hL|CYFN9%6m2JdpbA-?w|41BglXb0<<`HVvmKNoSIJ`J;AcnXb?4qRKUt1j9HWgx1eC?c z4VS-ucLhCuV6@uE9(KWG7MZKpwtv(p>EULgxl2l`@qFTI`$MFnEJ+-;)IQ+N0ptW2VGzPzg+ZXSIHW^}p zwq&q46`XSaYofdMU%nsfF`IgehDbddk*^DO4^DJVX!5VOKG8XDSWwS`*^Q;8YR+8K zk=vCTDoO!*j(W~s?v=j+$-p^!qgaM!zFz}tz);?krgi-LE&xSgWwGc$>3viVUSbO_ zHS{Wu$M1H!E#k_Hs~NoAf&uUIU1sWb^~tlODirv9^}rR_6#rP0V-uQ@*N85U+q*kv zlLbqTo55?z3BO3q`&kppOlVHm?}3T=Ow)Wd;AfjR<=@y}yoF31R|`kQ3*zk6Nq7jN zN~y=6V0Ljc@&`}Et3P2|_rn4uwwS=P?&};4n~>Y+G`?|xsUefsSt;o#XVBVpAITob z746SNp6&>A?rHhOmW8navS_&;R+)bGm6W7t&Yb>8WL%jmn(BbaBO zQ(R&WVkhg8>b;G^T=<3_ot9YVvGF;(pT zj=*~!A=x4Y++a6JF~)18p@Ssn%c$Oc#%gTYi{c(efFfa@dZP<^H*hrJ*BEsg+lH_ z&2!{^w;DY1sm<$Q$&jsk(}jSc0j+9dc#90Yb#c$o66xJJ`qjU;aG~XKug%mN^ev{A zTJv`~7)p6EE_Vwy!D$PI9Vs*&_Sf$;3ltgXt9^MtgC~<;LkV-i&*c^Z8~mQVa+@{K zw?z~)Qv%*gH)MX7G{=~;alg0{D{13|$U~p?XvgusMmq|tzcrjx7pmSk0;OmGonB^8 zu|ZminN66LPo~oG=}+G!hfI1`^W>~^?XY~3$V4C1A^vsq?O&^r;z-|HH>Kgn4Jo-qU`di)(9D^Dc6W7QCg-Eb-gLNm zUSF0!t}F+4H67ffhOL2OzrizeGn^p}K8IF~8UFl@9$I}cTMC!#eTf*=s;w*^T2>Xt z1ub@e=B)*IsAwUrWKAL-E>aXp!n2qP@x8k(4zq8@K?vIVIF}N$7JjWw>G1q^TPsQdg<$H};^SM}6A(bE%;t(R|9C4#$<{CiWACQULBRO)II3klBazw&FE>yE6zyxRhT+(p)tf?3tJ0ao}Q<0B^(Rcwq3 zHJp`Mh*fpG-~x%}?q2Slma(L_{c7t=WMO3F^v{zl(r|fyh!m?CC}R6nzjkG$h3>SP#tQ3n^=QE;W34^XF%AG%d_D$9+h5>o@MXtDkH*51zqWW~~kBPo| zglxzQ1_G~3p0(8%+|=3c#q4kPGT?a6iYobsK0h4q9-76V{$qjoaTH^cvM8-*G6CMM zg75_CeK*}k4$P3u(2_7IP?E1lVfdH|n}LpaCC!8GzJUMvqrI9PSYl~4=j?j-%T_O2 zAL&R9v?KArAGVqi)%hg)xunNf=`-1TV9`chD#i4bOJx7iFE0f&537A|qfan^2C{Wa z3U!%oU#VO!EqBZw3EAUSo4vMT-xU|yR%wS#!HjBH0&7Mkv_ReC*}Y#*YZPFgR>$Pg z3+zutMwNCAb?*U^!CK)kq9YP^-zPl@yLTuh>#b6_p=w8$FZHfk-EekN6YWr1uFrys zSdag8gck~ZEy!EINxxYz<)FDZ>K|oELTuSc4+n~~S83*< zaap13k6v=2WL>nJa(C|X6v;d7gXp&!<9xDj7K(z@tgoCWnYCy=XxV>qMw4R3qA^qV z=ma{)!kp=XLo&bC`zZ^21%S*Wpi`Nddu^&94>9-;JsyJoWM`6^SJ*)tLl{LOC*|V< zxL5L4XT|!|D}M87!dx~Ak$AxE1UQ~}d2Sko5X>ah2kFHI6k{K6C_BB zVEmTCe7pk>AWWzf1+3Cg5iR>O+JIBKs7Os=04}pWFydm4pO+!v<)2Xy*0ucChT$?$ zpAC@@Uj-Syv8XcmN> zn%Mju2Y<7al+{ki_C9idniaLBhXyDqNb#eE)zY12Br6thoS>TjQ8Tg}wEp{$T^ z+9_th$rhjQ^6QbSRq@j#j_~G45__p{z@esj=$L(9HA2d0OT7OD%fWU<_@Cx~5qmoq zERrocqJs+?pQjIog((2M^QEWP=N-kH>K%PB@*NFKaY9ZdZ_vVFk5g91BRcr4Q#ot3 zVsBM&Y#S2nzFVGUr7 z)KKjF%?D`A6UX=_z_&aeeYlX+s48aiZ`Pb#kP#ne2ByyC$<8b3dD493AW}u05Y1r% zZ9HZvlH&p7Ji?SU@>__{`IYguRJy!r-&hak8urs90JFYwRrMBEUQ`^+-`J>; zmZq%Wz??|+E$~s%*9SVY6)>ULwANY|$_E7#tX(S#%mv+9XiflJI3`$#l!aNVIHM*!#5!k@tzTO zX`F;E4}NK~cCQ_zs3kigHwMLV;9$J9IvZfO_U`7!-Pd}l-d#{^1y*NrAqj03T@RZa zSite0>V}QXB@H=NRYal9+Unc`W?UHGkqCOYsEE*PKk9#a-Kq85@9nk2UX!txhw5!1 zZo*EL=e*~CKTZ#{dmfqFUISG}b$p0NM&2pBm^vIa+q6%O1> zCP+V@`vTjvtCRoyR>lodI%F|J`)B&Ku|a_y<2wj%_)Z!Ap=qj_3!?1L!ux0xK@l96 zS&x_>P7HD>nK%;6d!Ai5gKX2#al!s%#6*@$MUUy;3_cdfYWzNvb|ROX z^pRq7>rviFf7RCdGO||E&+0leKJc0gb?G&LXExsJ{js`6Nkm@f{i^}rz?G_dX$&7j+64`=M_n*cRzeqq%*Gxt2dN>bdF1tdvJT8W zDeRUeF(uS7z)|+ZrF|FR>JM@ylP708rBH^Ggo=ny7GWLwR<~0w~z=M6#eV*TIpZ5=-fE>C^DC>UpPW;h2dH8=iW3P-bSg< znR7|N)iRe9ILD&k^Q{+i?UDjBHBO9?c`Wl-U$cajkdqOOYgSzK62uM2x(*7E8>a@c zP`+Tdz({U&mJ`Zxi=QnNl61(?X28($!Ay{GW7_5nw7`YJXn1L7uCZ}%Cx2h))OAr~Yr?8lad#KHw>XeKf;Ud` zucGC69sMM{h3 zdvEEEw8w^ip{jfkwLFu=FC}8iy-I@C&iB=cktLtQwhfff-u~xzWu`cEjuV92qnD#X zU-{5%kX~tIX-=l`KT8ai5_?iN&^Y_qJGIvHS!(Jr1S!@DrEsuIoO^YQ$8I5UR2|Tw zdjNPSWkloiZTu3w1pO6sA|K8#wzg>U~{`4bh39_1Qz%W5DLn*9nWvLtC(3KUCZW%!pnnsUxZr`mVUNIfNcGq?P)Q8UCn!AM*9+b48#AYIy`~B3m^qvZD8e^d?m^D3^!v2Edu(r+bMl&n17+A=_f*w`Ow%}?~rN}L6U=`)U3dE}$dTN$% znrojGvM>=E*T`M|B78HavNm88gUDTK)&Z6)0?4r_lzf2nel1}rf#&LslgFk{TBZ|g0~`0{{Xq$=e>o^^n6vT>Ai`Ki>DCB4BG%de%rHNe}VId5rS-<_!2EA;F?vV^?^h0B5 zo2oF5`((&y-$=LMDtkbWT}?7eV)XkmHc_owfjxIZ349=Yx(OJr^*4lVEKHvu*$z|* z1k?dqU6h8plMPz4??Mg**BtJ~eLWs2$+3Vf6gN8aL#WFd*WIr};w5K*y6Z)bT=O9& zY(>H_XBXPOw^!s0_;Y8w6-{o6AmAuHvmW*JwTWX$%%n&UZ%n;25Dv$6X z+vPRTd{l2ndv9HK)m;j#zz%95aTFiSzT`(JT(R1PCz$Mb@m8;-7&V3T&hk`gwv2*e z;g%S4`L6og`@wf)|7(W8--NkpPCm0xH;s9I3zE)caT5UN2rZ;2poJos2?HLB(UdcF zZn*pDrdp50arb|~s?WHit`KnTSfi6MYAe{UJJr9lYBy%{dz>IuSb$i)CpB6^Q3|p6 zZ#&2@_7Q#u%R(CH`!jfnuoSblE~mA`btY1EP+-x1;_A2O+HT>h0h$669G4sFqth2> zb~AK)n`lO!HY=NzlChP&e3qjgy5+A^YZ8mX7;RT$UZQ}Cdb6y${TjH72?wp!<0fQ_ zEl!AVJY!Z*PZf+B-@X?LTPJy0J$5KSh{o4@N;BGVw#JmbV3cPhJpAE&2N3CZh6g`u z&H%KWe#8CsS}PosC|AxN4L~zajGg>74-CB>?Cx+ewt4|3-@Evu>Amq($>`>DA;0-r zP=DM&R4k!|zV=nuw!mLY9CEDXd;Bvuh!t?9A2*`R4Nm*mz30WrUx`owPU zgQrGp`bWk$EHnK|skILjhP!VmT}gQmur114FR*d1aADv2llFH3GGHS6qlK;v_I~&} z!QFNt2+;Hc3TgG1cLXNb*@A;TseIEvVg^7t4sl^xTyD(e4&Ish{YKW?6=(4x$*kgY zlRz4oOxu`D@cH#7?eA- zS$F3^^l>O|e#~Ts{wiU@WQJAoK<r5 zvfNptslxJ+n;-u!y{7gO6=Pi(E0ZH#9e11F;6>Za?{4U51r}t0;EX%PFA>n&>CBb! z=RcmJ!4Wz^NN$pA=Vm%VT><;?tt5{_kN?@f{+bJ)>dGH9<*e7J7{klW?$;To7T%?H zaH!}RYQU{UiUwo22ov^*{+e{q5O!e~%IFKuOJm-D|CsCXdN+F%%HiOsPa(a1pcmsm zZzC4~t0XsvyP4kcD;!eR3U%yxiFm?xu24uAd}&s}_?JSEIvcsBhDiaL63~YB91&qp zCcZh^?$oOA`xgh!kG-63KNkgWCc4Hh5mO|=@!7uuTk(6Dj!;-sOs7)O z8#ImS{Y3i9{PSxIPQcPUF{`DpM|Eai@t>U7c=fOnCV2}7yvP~a*+0FcfV*pKbwTTF zz6A@IyqQPnp)!_ZmxHJmvcpN#ie3A|z@1)!wN2|)-nr^C`N-zWjZz-)@doxP%ntin z3M2gohNFCLF4FHyBCe75)zYl>?-G@m6{8;5F<>;>-=r#|Idi@1*_+%_Ra4~>hf@*v zT+isaaDL@|()gZtLFkQeiIFGSx|!0O4|RMs__}cWQVM~uGMp- z*6uK&1ioA0oM#c-*DEfYLuK`8;i?yH4WKvb(Bh&Olel~ zDPp#BlCQQ;3%PcrE(4grk7d9@ca7xv=T|QO=1la%D|2UUPkq8S^OwTYmafU7Mo7OS zDsk@)F=pC@b5_6@cQ-@YqvcR4&P;<8i$ML$29MR?m7U%;r5LFWXJaXM$KhN}WxvDF zk?%+nMbcUI$MhGL_Nf}FI_MVoR~Rtunf~Yga>*&{sviYztJcJUk^7PKDhTZu!$Uw$ zhHZ}>ykhHFE*8CuiDL|mEIqly4%zwaq9J5T!B+#S>Bw@-yr9TfSfW=4FNCB zvE2RI$FL{I26pJ^E>&7|(|`U)uey;DQ#LYM&7&)4KCmMgX7wul0b=y3pTZqf#HjUW z=j)a3Ke69x^a2&nM%vc)8IYE@&a3jLy&q*ecd5Jw#i_ERw%%FSy_FxY+l}O&m_g6F z$r%Z}I1EoP=&G6*h#(a`PgS5P8Z6i}6DuhACd=@Vy^&CSR+5RsZ(N5+R2~qu z?%%uPqH`U@4w@9>b`;|F1KmWXtRa|VztvYeYv|!|^RU2tX?>aT+*Z3qZM>JQYtz*% zNhfi=V)yG9Jx80BKToa&pSX*$IiVB<{fn{IpB2}}R@*8s9BBLTL%@KBlmO5R%z4u^ zxFM-%`hlwJ?Nac4_HuaDfXn9_n-ZFZ0wUQj_WEPQVDHV#Wsu$O0VOqTQ{w&1CV2Ig zw0&j#sOv zQ*r`@1LTl~9@%Sebc!WytKg6K9rioaNCFLt`M= zl;PmEP*PZ+J)ykM6)Of-YI!#!F6UvuE(;ek^yoXCv`XT(Teqycd~j+^4xy%e+#yG+ z_CeaFJy?1wH>hjMsU%L>cGC%w16D;D!`n{bw^~&;+xL|#sk~@^l7h(K z$~2#xz~!pw8Qq`RaPQD{*yFVd{jF93{JX&A?OPj@-$7HmZF?o?tpSp4d z$jwz-t98-UoR3fHa40n-p%6FTj7Rut9lBP@fCA86IQap^dBMV>(F=R=4FvI~Uv3P}|SHSy5}B> zfII9Ahk(Cf=-zzD3XR#e%Te^Wb(Uiv(Ux^A^)hwZk%CWleA2K2duHhXsm5*xJ0Xf- z&Wwa46Q?yd;HB#gby~ai0BtjW;`_^y0)VjKf8A-ai*CSn5T7nCS7Kyj0VuQ&uh*kL z39+cHb>v2(Sdbg&qFD~CR&0?;pD?36i%2o_ENQD+(;3AypQLEh*d>!8Eu(&+c^kGo z0r5Wh!lPh{!)olX+>v+d^KVVLwIsJtdx;C{*Y0+O4;QEZo`UE1n7t#W!?0fcCj__@@LYCm3C1L~5%hYcdMW^ak^y)Z4z+fB6f5O8-to$)dN}GPq%mO}UkSiwE6vuy2K@Lsq%!n7 zQF>yiIr&k~wo>CEG(9RblJo-n1;xQUAP*_($UQV>374bV3J^(J8`7SLmc{MB{0 z=5jwvScil9CPSl_sS<*nOja5kN^-hzQ67Y4!sr2A1FoL{mV2&$$uT1{5=nW$e5YZS zcjLh;pVWXbWXaGynWUW{S`8m`R6i`)G|hDq`-DBJy#E%_AuJgfsO{ZieFP8)dm{C;95DskA8<_?G)(`5-sy-fIb^dqh z;F9i)hZ+U9&+{XLS~ zw;eGkhpDwhUr%3YKa=c);T9$;$78m?vCjVUv9x`&TH;;CeI&fTKXYvtXIFwmc#o`2 z2Ug`ZjIgwN+WCV1PwHP#R9HF5vEw+N{v-FmNCnny0Xv^BU7di3KwJnmJ|#WHpwh0F zuJ&JTvq$*@hbT#cbO~_J&g1a8`i~x8qb1UkxXrOop-MKN9F=2sje&^!+rE>i86*p~ z@`lK$ArlQeF}z_8Vd^B#5GTG%L?V?~W=aEoDl!8CX2Ne?i%97a@Ua;+V{HXi#~6s7 zHb1UXRqF(9%SRyyzN2F+vx=*6&ZME+uvi#qTMWh|Sy3<&=>5}KCRyNwFQ8da$6wC@ z_3LHCdqx2#1RUXO#R?{1U8brGRQ}1e+%y;Ilay`|J^xmGEtf?ynt>)j#CK5pn3jw&}}uH{Yd>!+lL1r--TsD93NPZ@{IrkJ9NZ z-v)%+*yMtX02MSg4a+FE*yuJ#wf^0m3u}qK;lB8uk+6D-;eF@6 zxRzsaP_k2HAFKZMEpSTdcsZ?AACE5_x~VC!41KQZ(115fNH;ynP4?JQkA7Sn9TChIKW)(ubIMBcR!O9**?Su+p zAb>)=Y+Y`in-DIY+}o$nEvQuV_IEQ}Ca#V(bL=P@zd)vsb@99P&3`d}m=p=tcJXb~ zrv~ced5FD2p?aY_Rt$uHVcs~WwGq||?2Wl3usi^zlj!@Dr-vJ1r#p6^o?Z3bd=Env zWi{4Vi$bn&qpT-@zyk;%S=XvtS7 zP8VvYl28$eNR;+*m)%#d#GodD2O)@r&J4%>q~|Hq!mJ@E3SNjrFaKsQa33XgK7Gz- zryHNJ$8{dWtiUCetvpf~p-{K*qM;`Z%}%i9by_oUxv-we#)k;@I7TS=92f{r{j`IX zQ{y=7Z4=lYn|Aim*Kqv2=Pw_iGO~c4G1kzpaVOAJaI;5Vi=-1I%tgr1*0|?(Lp*O* zztZNh2T_0~tLKj8qBRRKj{-B*0h>3;^ZfV*DkF92J*k?04g-aUL}TnrcwN#~hx~YM z2|b;(ogim1QPLK;#PB_=Ve|$u{WC-bobk|ODM|dx z-Vw}>QckW}wlK!kQid|UNdI~({NA7ZarMY@y+8R8!(q!;Y3Raca+DZuR7fGCqCe7XckuPb>wFwHX`J@vU;8|k&%`vi#xX0GAe zvK#5+N6}j!5-Wo~4;sp;r528}KtGRH0g<$4^>$To98cGFMV*OzRC z2azb?Vq=d$;Uf&Qzj`di$|T9YZh$UX)v{6{rGX;!7C(-6TlX<_Le9~p4`EC9aEe|xB#(T zi`T6WJF|6lBjP6eXDC#-Og5nQu|>YGW+%>lfW?!O$8OfS$1bvs?|AlNbkviG&^!aC{`y7FDN9M zNdr?qehlBwgtZj}TXE*&ct8KV$pw}~GeCC#*Zk6yb3V=R-@5>&|8LX(taSypxdQLT z#VdgBVnqS)`oC9(02`FRIQs7|ivW52_xf)c0PyaAPeSy+_vC+85CNm%f5*xH&Yk~_ iCtxD{zYrdA=M+s^`NaS3a(7*X^n2=hY9%U9-~Jy@Oz)Ba literal 0 HcmV?d00001 diff --git a/packages/officesupplies/images/mug.png b/packages/officesupplies/images/mug.png new file mode 100644 index 0000000000000000000000000000000000000000..a295417f7baab3ab234f9ac215161102762e7f04 GIT binary patch literal 18063 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 Qfu4Fc z1-}Th4T}$m(TT3ic>51Sf|(``0WZ1~^q3I0(rJC-2c=){9>)yjW7fXD1UW-VsTtdt za?t9VG^GG4*Za@Yfl?)hzb9ikQwDzNaZRBu{mZhh9awR+15d5VDs6Gc)}5W0KA0na z0hcWcl1snrPBXMNGH*7^=21YA9$rFIjqI&*);YrN7hmWylkdE>>)Sl|qS>_F zx+di)cTNL!3}RX#W=1WRPK0q5Ne2%xlda+#BEdm`>$ic+Nw`}#di=TSQzj5A3CAJ9 z7QH|P^R47}{yW8uC-#%#8jQ>G8W%75QYq@CsDuW`yo!tk^^J)r;>X*dGp{qbqIrXp z2^{D%y6?28$uMq=w+;mCWN$HpGGo2C)_8t3bI%}AV;`l{E32hTOPb>_`z-DA6^ukr zr+VF`ft)u2Hri@*e+(Qv?)I*{MdkmnENkV;9N&Bs`~Jw~-wJX*e>Yq_1xd>W&aAZd zVMSUQ9*`3lxTg+43#XN16aBGVl6@PDZZnF_jF|RPKLa^S9#nEhH=ae{66FXTh^t?b zu{d&;4k}%XB>#KY*!KW{t792~a)HxxwOha!oAv-slT|3s2;?P#i=osOAHoedms{O8 z{Oaw}^ChZ{1dxl3^IyTXlmvDO;)mo_fmM(PO&ek!g)szFml5mEAqo+z57m;NZ+sti2*OJ0O>bi@8-DY!RlVLY(n!) zig4vbm@Bq+?LFrJ-B8ts0ES<@yDA^YOTl>y`#w1})jg$paaCvA$A}r+;_~p5IOxxy z@oC<)0&(4eSk-**`K%WFHpLeCV;8CF%h@d(S;|o_C%}CO>+h+`13mT2nUS%o#~_;X z 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

A08vu zH~iXQj-c(8$Qi4tlX7LAbu9EiA@0eP|FBO*6OP7uABVCtiuL zz)XK%Ft0!F^pqOiV!P0_U8Ds8omDX}hH7&@Z6t^X2{mu4#r>s>rvL*+>Og3(Q1%>B96t@bt9LP9fUz1@IVkYR*}@((lXBHmPu zdI^(j;LKhI!qb87!za3uA=kLnOKUOjDFHtt(GRPQLshX7)F2*u6HPalWH8k!I}*0v z)FJ2uKm6|k+;*;-1?Gi5a4hMl7b!euJ^eBs8HlNOV1wWK2o1@${wRnWx8yqgB&DYy z;1+Ir36^w+cf{~*^Fz_53>Uw~gp=LKqb!bkc~Y%n*$8QFcv_J)g{6oB$+i?UeB zkEDDz_YT)?r_SpZuu6l}`vUmd9-mt#nORE}@#=rwj`qgig}`v83z8Oaef<=Y5%GI+)D1Tg9xF^`ZipCJjCj0^CN+mP)(QD z%eU<#wscP%p4_)RN3h|N>*^6$<&uKu_U8UQd1|xkY9n$^>TtYk+0S}0gZ7iJo1bzJ zC9DiHx;@>6;=P#P*Cb&sAgCz_U>r#_q!ZFv3f4jRcnSfBYq|-@gbQvGRxd z|JY05P2it;fMo`X06&fh{g1u;qs1daN2)y{^gsBL0Pdsx=cM~DYW$B#2ixoa{~j9V x&JE=J&&A*W4)p&-{2gVK|Kd3R&-hCwbF#iUZg@@G;y$bemD~4}N^Y74|6d#{A20v_ literal 0 HcmV?d00001 diff --git a/packages/officesupplies/images/pen.png b/packages/officesupplies/images/pen.png new file mode 100644 index 0000000000000000000000000000000000000000..f3cc74462879d3a00d293c66bbbfa5bb55bee601 GIT binary patch literal 20974 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 literal 0 HcmV?d00001 diff --git a/packages/officesupplies/package.json b/packages/officesupplies/package.json new file mode 100644 index 00000000..de142c2b --- /dev/null +++ b/packages/officesupplies/package.json @@ -0,0 +1,14 @@ +{ + "name": "officesupplies", + "version": "1.0.0", + "description": "A simple CAP project.", + "repository": "", + "license": "ISC", + "dependencies": { + "@sap/cds": "^3", + "express": "^4" + }, + "scripts": { + "start": "npx cds run" + } +} diff --git a/packages/officesupplies/srv/cat-service.cds b/packages/officesupplies/srv/cat-service.cds new file mode 100644 index 00000000..6d4cda41 --- /dev/null +++ b/packages/officesupplies/srv/cat-service.cds @@ -0,0 +1,71 @@ +using sap.capire.officesupplies from '../db/schema'; + +service CatalogService { + entity Products as projection on officesupplies.Products; + entity Suppliers as projection on officesupplies.Suppliers; +}; + +annotate CatalogService.Products with @( + UI: { + HeaderInfo: { + TypeName: '{i18n>Cat.TypeName}', + TypeNamePlural: '{i18n>Cat.TypeNamePlural}', + Title: { $Type: 'UI.DataField', Value: title } + }, + SelectionFields: [ identifier, title, availability, price], + LineItem: [ + {$Type: 'UI.DataField', Value: image_url}, + {$Type: 'UI.DataField', Value: identifier}, + {$Type: 'UI.DataField', Value: title}, + {$Type: 'UI.DataField', Value: availability}, + {$Type: 'UI.DataField', Value: price} + ], + HeaderFacets: [ + {$Type: 'UI.ReferenceFacet', Target: '@UI.FieldGroup#ProductDetail', Label:'{i18n>Cat.HeaderFacetDetails}' }, + {$Type: 'UI.ReferenceFacet', Target: '@UI.FieldGroup#SupplierDetail', Label:'{i18n>Cat.HeaderFacetSupplier}' }, + {$Type: 'UI.ReferenceFacet', Target: '@UI.DataPoint#Price'} + ], + Facets: [ + { + $Type: 'UI.CollectionFacet', + Label: '{i18n>Cat.FacetProductInformation}', + Facets: [ + {$Type: 'UI.ReferenceFacet', Target: '@UI.FieldGroup#Description', Label: '{i18n>Cat.FacetSectionDescription}'}, + ] + } + ], + DataPoint#Price: {Value: price, Title: '{i18n>Cat.HeaderPrice}'}, + FieldGroup#Description: { + Data:[ + {$Type: 'UI.DataField', Value: description} + ] + }, + FieldGroup#ProductDetail: { + Data:[ + {$Type: 'UI.DataField', Value: identifier}, + {$Type: 'UI.DataField', Value: availability} + ] + }, + FieldGroup#SupplierDetail: { + Data:[ + {$Type: 'UI.DataField', Value: supplier.identifier}, + {$Type: 'UI.DataField', Value: supplier.postCode}, + {$Type: 'UI.DataField', Value: supplier.phone} + ] + } + } +); + +annotate CatalogService.Products with { + ID @( Common: { Label: '{i18n>Cat.ProductID}'} ); + availability @( Common.Label: '{i18n>Cat.ProductStock}' ); + price @( Common.Label: '{i18n>Cat.ProductPrice}', Measures.ISOCurrency: currency_code ); + description @( Common.Label: '{i18n>Cat.ProductDescr}' ); + image_url @( Common.Label: '{i18n>Cat.ProductImage}', UI.IsImageURL: true); +} + +annotate CatalogService.Suppliers with { + identifier @( Common : { Label: '{i18n>Cat.SuppliersIdentifier}', Text: name, TextArrangement: #TextFirst } ); + postCode @( Common : { Label: '{i18n>Cat.SuppliersPostCode}', Text: city, TextArrangement: #TextFirst } ); + phone @Common.Label: '{i18n>Cat.SuppliersPhone}'; +} \ No newline at end of file diff --git a/packages/orders-service/db/data/sap.capire.orders-OrderItems.csv b/packages/orders-service/db/data/sap.capire.orders-OrderItems.csv deleted file mode 100644 index 1b5ff074..00000000 --- a/packages/orders-service/db/data/sap.capire.orders-OrderItems.csv +++ /dev/null @@ -1,4 +0,0 @@ -ID;amount;parent_ID;article -58040e66-1dcd-4ffb-ab10-fdce32028b79;1;7e2f2640-6866-4dcf-8f4d-3027aa831cad;201 -64e718c9-ff99-47f1-8ca3-950c850777d4;1;7e2f2640-6866-4dcf-8f4d-3027aa831cad;271 -e9641166-e050-4261-bfee-d1e797e6cb7f;2;64e718c9-ff99-47f1-8ca3-950c850777d4;252 \ No newline at end of file diff --git a/packages/orders-service/db/data/sap.capire.orders-Orders.csv b/packages/orders-service/db/data/sap.capire.orders-Orders.csv deleted file mode 100644 index 143da2c3..00000000 --- a/packages/orders-service/db/data/sap.capire.orders-Orders.csv +++ /dev/null @@ -1,3 +0,0 @@ -ID;modifiedAt;createdAt;createdBy;modifiedBy;OrderNo;currency_code -7e2f2640-6866-4dcf-8f4d-3027aa831cad;;2019-01-31;john.doe@test.com;;1;EUR -64e718c9-ff99-47f1-8ca3-950c850777d4;;2019-01-30;christian.georgi@sap.com;;2;EUR \ No newline at end of file diff --git a/packages/orders-service/db/schema.cds b/packages/orders-service/db/schema.cds deleted file mode 100644 index f7d7b4fc..00000000 --- a/packages/orders-service/db/schema.cds +++ /dev/null @@ -1,15 +0,0 @@ -namespace sap.capire.orders; -using { Currency, cuid, managed } from '@sap/cds/common'; - - -entity Orders : cuid, managed { - OrderNo : String @title:'Order Number'; //> readable key - Items : Composition of many OrderItems on Items.parent = $self; - currency : Currency; -} - -entity OrderItems : cuid { - parent : Association to Orders not null; - article : String; - amount : Integer; -} diff --git a/packages/orders-service/index.cds b/packages/orders-service/index.cds deleted file mode 100644 index 8e460ac4..00000000 --- a/packages/orders-service/index.cds +++ /dev/null @@ -1,2 +0,0 @@ -namespace sap.capire.orders; -using from './srv/orders-service'; diff --git a/packages/orders-service/package.json b/packages/orders-service/package.json deleted file mode 100644 index f8341b12..00000000 --- a/packages/orders-service/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "@sap/capire-orders", - "version": "1.0.0", - "description": "A reuse package providing domain models and services to submit and manage purchase orders.", - "repository": "https://github.com/SAP-samples/cloud-cap-samples.git", - "license": "SAP SAMPLE CODE LICENSE", - "dependencies": { - "@sap/cds": "latest", - "express": "*" - } -} diff --git a/packages/orders-service/srv/orders-service.cds b/packages/orders-service/srv/orders-service.cds deleted file mode 100644 index 766cc012..00000000 --- a/packages/orders-service/srv/orders-service.cds +++ /dev/null @@ -1,6 +0,0 @@ -namespace sap.capire.orders; -using { sap.capire.orders as my } from '../db/schema'; - -service OrdersService { - entity Orders as projection on my.Orders; -} diff --git a/packages/products-service/db/schema.cds b/packages/products-service/db/schema.cds deleted file mode 100644 index 573e93ad..00000000 --- a/packages/products-service/db/schema.cds +++ /dev/null @@ -1,18 +0,0 @@ -namespace sap.capire.products; - -using { Currency, cuid, managed, sap.common.CodeList } from '@sap/cds/common'; - -entity Products : cuid, managed { - title : localized String(111); - descr : localized String(1111); - stock : Integer; - price : Decimal(9,2); - currency : Currency; - category : Association to Categories; -} - -entity Categories : CodeList { - key ID : Integer; - parent : Association to Categories; - children : Composition of many Categories on children.parent = $self; -} diff --git a/packages/products-service/index.cds b/packages/products-service/index.cds deleted file mode 100644 index 581fba09..00000000 --- a/packages/products-service/index.cds +++ /dev/null @@ -1,2 +0,0 @@ -using from './db/schema'; -using from './srv/admin-service'; diff --git a/packages/products-service/package.json b/packages/products-service/package.json deleted file mode 100644 index 3415c423..00000000 --- a/packages/products-service/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "@sap/capire-products", - "version": "1.0.0", - "description": "A reuse package providing domain models and services to manage product catalogs.", - "repository": "https://github.com/SAP-samples/cloud-cap-samples.git", - "license": "SAP SAMPLE CODE LICENSE", - "dependencies": { - "@sap/cds": "latest", - "express": "*" - }, - "files": [ - "db", - "srv", - "index.cds" - ] -} \ No newline at end of file diff --git a/packages/products-service/srv/admin-service.cds b/packages/products-service/srv/admin-service.cds deleted file mode 100644 index a7ebd575..00000000 --- a/packages/products-service/srv/admin-service.cds +++ /dev/null @@ -1,7 +0,0 @@ -using { sap.capire.products as db } from '../db/schema'; -namespace sap.capire.products; - -service AdminService @(_requires:'admin') { - entity Products as projection on db.Products; - entity Categories as projection on db.Categories; -} diff --git a/packages/products-service/tests/categories.test.js b/packages/products-service/tests/categories.test.js deleted file mode 100644 index 8e541a4b..00000000 --- a/packages/products-service/tests/categories.test.js +++ /dev/null @@ -1,68 +0,0 @@ -const cds = require ('@sap/cds') - -describe('reading/writing hierarchies', ()=>{ - - it ('should prepare to sqlite in-memory', async()=>{ - await cds.deploy (__dirname+'/../db') .to ('sqlite::memory:') - expect (cds.model) .toBeDefined() - }) - - it ('should insert hierarchy of categories', ()=>{ - const { Categories } = cds.entities - return INSERT.into (Categories) .entries ( - { ID:100, name:'Some Sample Categories...', children:[ - { ID:101, name:'Cat', children:[ - { ID:102, name:'Kitty', children:[ - { ID:103, name:'Kitty Cat', children:[ - { ID:104, name:'Aristocat' } ]}, - { ID:105, name:'Kitty Bat' } ]}, - { ID:106, name:'Catwoman', children:[ - { ID:107, name:'Catalina' } ]} ]}, - { ID:108, name:'Catweazle' } - ]} - ) - }) - - it ('should read categories with children', async()=>{ - const { Categories } = cds.entities - expect (await - - SELECT.one.from (Categories, c=>{ - c.ID, c.name.as('parent'), c.children (c=>{ - c.name.as('child') - }) - }) .where ({name:'Cat'}) - - ) .toMatchObject ( - - { ID:101, parent:'Cat', children:[ - { child:'Kitty' }, - { child:'Catwoman' }, - ]} - - ) - }) - - it ('should read hierarchy of categories', async()=>{ - const { Categories } = cds.entities - expect (await - - SELECT.one.from (Categories, c=>{ - c.ID, c.name, c.children (c=>{ c.name },{levels:3}) - }) .where ({name:'Cat'}) - - ) .toMatchObject ( - - { ID:101, name:'Cat', children:[ - { name:'Kitty', children:[ - { name:'Kitty Cat', children:[ - { name:'Aristocat' }, ]}, - { name:'Kitty Bat' }, ]}, - { name:'Catwoman', children:[ - { name:'Catalina' } ]}, - ]} - - ) - }) - -}) diff --git a/packages/products-service/tests/data/sap.capire.products-Categories.csv b/packages/products-service/tests/data/sap.capire.products-Categories.csv deleted file mode 100644 index 20183828..00000000 --- a/packages/products-service/tests/data/sap.capire.products-Categories.csv +++ /dev/null @@ -1,10 +0,0 @@ -ID;parent_ID;name -0;;Some Sample Categories... -1;;Cat -2;1;Kitty -3;2;Kitty Cat -4;3;Aristocat -5;2;Kitty Bat -6;1;Catwoman -7;6;Catalina -8;;Catweazle diff --git a/packages/products-service/tests/postman.json b/packages/products-service/tests/postman.json deleted file mode 100644 index 6fbc8a8c..00000000 --- a/packages/products-service/tests/postman.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "info": { - "_postman_id": "0f8d4e79-a1c2-47fe-aeab-0319fb4ce180", - "name": "@sap/capire-products", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "Categories", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{ \"ID\":0, \"name\":\"Some Sample Categories...\", \"children\":[\n { \"ID\":1, \"name\":\"Cat\", \"children\":[\n { \"ID\":2, \"name\":\"Kitty\", \"children\":[\n { \"ID\":3, \"name\":\"Kitty Cat\", \"children\":[\n { \"ID\":4, \"name\":\"Aristocat\" }\n ]},\n { \"ID\":5, \"name\":\"Kitty Bat\" }\n ]},\n { \"ID\":6, \"name\":\"Catwoman\", \"children\":[\n { \"ID\":7, \"name\":\"Catalina\" }\n ]}\n ] },\n { \"ID\":8, \"name\":\"Catweazle\" }\n]}\n" - }, - "url": { - "raw": "http://localhost:4004/admin/Categories", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "4004", - "path": [ - "admin", - "Categories" - ] - } - }, - "response": [] - }, - { - "name": "Categories", - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:4004/admin/Categories/0?$expand=children($expand=children($expand=children($expand=children)))", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "4004", - "path": [ - "admin", - "Categories", - "0" - ], - "query": [ - { - "key": "$expand", - "value": "children($expand=children($expand=children($expand=children)))" - } - ] - } - }, - "response": [ - { - "name": "Categories", - "originalRequest": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:4004/admin/Categories/0?$expand=children($expand=children($expand=children($expand=children)))", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "4004", - "path": [ - "admin", - "Categories", - "0" - ], - "query": [ - { - "key": "$expand", - "value": "children($expand=children($expand=children($expand=children)))" - } - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "X-Powered-By", - "value": "Express" - }, - { - "key": "OData-Version", - "value": "4.0" - }, - { - "key": "content-type", - "value": "application/json;odata.metadata=minimal" - }, - { - "key": "Date", - "value": "Tue, 21 May 2019 19:20:24 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - }, - { - "key": "Content-Length", - "value": "767" - } - ], - "cookie": [], - "body": "{\n \"@odata.context\": \"$metadata#cats(children(children(children(children()))))/$entity\",\n \"@odata.metadataEtag\": \"W/\\\"+AAp4JKNOcr+OusjrdQo55RCfM+UHKpTh8EbhsxyPhM=\\\"\",\n \"name\": \"Some Sample Categories...\",\n \"descr\": null,\n \"ID\": 0,\n \"parent_ID\": null,\n \"children\": [\n {\n \"name\": \"Cat\",\n \"descr\": null,\n \"ID\": 1,\n \"parent_ID\": 0,\n \"children\": [\n {\n \"name\": \"Kitty\",\n \"descr\": null,\n \"ID\": 2,\n \"parent_ID\": 1,\n \"children\": [\n {\n \"name\": \"Kitty Cat\",\n \"descr\": null,\n \"ID\": 3,\n \"parent_ID\": 2,\n \"children\": [\n {\n \"name\": \"Aristocat\",\n \"descr\": null,\n \"ID\": 4,\n \"parent_ID\": 3\n }\n ]\n },\n {\n \"name\": \"Kitty Bat\",\n \"descr\": null,\n \"ID\": 5,\n \"parent_ID\": 2,\n \"children\": []\n }\n ]\n },\n {\n \"name\": \"Catwoman\",\n \"descr\": null,\n \"ID\": 6,\n \"parent_ID\": 1,\n \"children\": [\n {\n \"name\": \"Catalina\",\n \"descr\": null,\n \"ID\": 7,\n \"parent_ID\": 6,\n \"children\": []\n }\n ]\n }\n ]\n },\n {\n \"name\": \"Catweazle\",\n \"descr\": null,\n \"ID\": 8,\n \"parent_ID\": 0,\n \"children\": []\n }\n ]\n}" - } - ] - }, - { - "name": "Categories", - "request": { - "method": "DELETE", - "header": [], - "body": { - "mode": "raw", - "raw": "" - }, - "url": { - "raw": "http://localhost:4004/admin/Categories/0", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "4004", - "path": [ - "admin", - "Categories", - "0" - ] - } - }, - "response": [] - } - ] - -} \ No newline at end of file diff --git a/packages/reviews-service/db/schema.cds b/packages/reviews-service/db/schema.cds deleted file mode 100644 index 9b07b02b..00000000 --- a/packages/reviews-service/db/schema.cds +++ /dev/null @@ -1,31 +0,0 @@ -namespace sap.capire.reviews; -using { User } from '@sap/cds/common'; - -// Reviewed subjects can be any entity that is uniquely identified -// by a single key element such as a UUID -type ReviewedSubject : String(111); - -entity Reviews { - key ID : UUID; - subject : ReviewedSubject; - reviewer : User; - rating : Rating; - title : String(111); - text : String(1111); - date : DateTime; - likes : Composition of many Likes on likes.review = $self; - liked : Integer default 0; // counter for likes as helpful review (count of all _likes belonging to this review) -} - -type Rating : Decimal(3,2) enum { - Best = 5; - Good = 4; - Avg = 3; - Poor = 2; - Worst = 1; -} - -entity Likes { - key review : Association to Reviews; - key user : User; -} \ No newline at end of file diff --git a/packages/reviews-service/index.cds b/packages/reviews-service/index.cds deleted file mode 100644 index c126bf5e..00000000 --- a/packages/reviews-service/index.cds +++ /dev/null @@ -1 +0,0 @@ -using from './srv/reviews-service'; diff --git a/packages/reviews-service/package.json b/packages/reviews-service/package.json deleted file mode 100644 index 990f4e35..00000000 --- a/packages/reviews-service/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "@sap/capire-reviews", - "version": "1.0.0", - "description": "A reuse service providing generic means to add reviews and ratings to target objects, e.g. products.", - "repository": "https://github.com/SAP-samples/cloud-cap-samples.git", - "license": "SAP SAMPLE CODE LICENSE", - "dependencies": { - "@sap/cds": "latest", - "express": "*" - }, - "scripts": { - "start": "cds run --in-memory?", - "watch": "cds watch" - }, - "files": [ - "db", - "srv", - "index.cds" - ], - "cds": { - "requires": { - "db": { - "kind": "sql" - }, - "messaging": { - "kind": "file-based-messaging" - } - } - } -} \ No newline at end of file diff --git a/packages/reviews-service/srv/reviews-service.cds b/packages/reviews-service/srv/reviews-service.cds deleted file mode 100644 index 9634c183..00000000 --- a/packages/reviews-service/srv/reviews-service.cds +++ /dev/null @@ -1,41 +0,0 @@ -using { sap.capire.reviews as my } from '../db/schema'; -namespace sap.capire.reviews; - -service ReviewsService { - // Sync API - entity Reviews as projection on my.Reviews excluding { likes } - action like (review:Reviews.ID); // TODO: can be a bound action in OData - action unlike (review:Reviews.ID); // TODO: can be a bound action in OData - - // Async API - event reviewed : { subject: Reviews.subject; rating: Decimal(2,1) }; - - // Input validation - annotate Reviews with { - subject @mandatory; - title @mandatory; - rating @mandatory @assert.enum; - } - - // Auto-fill reviewers and review dates - annotate Reviews with { - reviewer @cds.on.insert:$user; - date @cds.on.insert:$now; - date @cds.on.update:$now; - } - -} - - -// Access control restrictions -annotate ReviewsService.Reviews with @restrict_:[ - { grant:'READ', to:'any' }, // everybody can read reviews - { grant:'CREATE', to:'authenticated-user' }, // users must login to add reviews - { grant:'UPDATE', to:'authenticated-user', where:'reviewer=$user' }, - { grant:'DELETE', to:'admin' }, -]; - -annotate ReviewsService with @restrict_:[ - { grant:'like', to:'identified-user' }, - { grant:'unlike', to:'identified-user', where:'user=$user' }, -]; diff --git a/packages/reviews-service/srv/reviews-service.js b/packages/reviews-service/srv/reviews-service.js deleted file mode 100644 index ae24ebba..00000000 --- a/packages/reviews-service/srv/reviews-service.js +++ /dev/null @@ -1,41 +0,0 @@ -const cds = require ('@sap/cds') -module.exports = cds.service.impl (function(){ - - // Get the CSN definition for Reviews from the db schema for sub-sequent queries - // ( Note: we explicitly specify the namespace to support embedded reuse ) - const { Reviews, Likes } = this.entities ('sap.capire.reviews') - - // Emit an event to inform subscribers about new avg ratings for reviewed subjects - // ( Note: req.on.succeeded ensures we only do that if there's no error ) - this.after (['CREATE','UPDATE','DELETE'], 'Reviews', async(_,req) => { - const {subject} = req.data - const {rating} = await cds.transaction(req) .run ( - SELECT.one (['round(avg(rating),2) as rating']) .from (Reviews) .where ({subject}) - ) - req.on ('succeeded', ()=>{ - console.log ('< emitting:', 'reviewed', { subject, rating }) - this.emit ('reviewed', { subject, rating }) - }) - }) - - // Increment counter for reviews considered helpful - this.on ('like', (req) => { - if (!req.user) return req.reject(400, 'You must be identified to like a review') - const {review} = req.data, {user} = req - const tx = cds.transaction(req) - return tx.run ([ - INSERT.into (Likes) .entries ({review_ID: review, user: user.id}), - UPDATE (Reviews) .set({liked: {'+=': 1}}) .where({ID:review}) - ]).catch(() => req.reject(400, 'You already liked that review')) - }) - - // Delete a former like by the same user - this.on ('unlike', async (req) => { - if (!req.user) return req.reject(400, 'You must be identified to remove a former like of yours') - const {review} = req.data, {user} = req - const tx = cds.transaction(req) - const affectedRows = await tx.run (DELETE.from (Likes) .where ({review_ID: review,user: user.id})) - if (affectedRows === 1) return tx.run (UPDATE (Reviews) .set ({liked: {'-=': 1}}) .where ({ID:review})) - }) - -}) diff --git a/packages/reviews-service/tests/messaging.test.js b/packages/reviews-service/tests/messaging.test.js deleted file mode 100644 index a814a79d..00000000 --- a/packages/reviews-service/tests/messaging.test.js +++ /dev/null @@ -1,69 +0,0 @@ -const _model = __dirname+'/..' -const cds = require ('@sap/cds') - -describe('messaging tests', ()=>{ - - it ('should bootstrap sqlite in-memory db', async()=>{ - const db = await cds.deploy (_model) .to ('sqlite::memory:') - expect (db.model) .toBeDefined() - }) - - let srv - it ('should serve reviews services', async()=>{ - srv = await cds.serve('ReviewsService') .from (_model) - expect (srv.name) .toMatch ('ReviewsService') - }) - - let N=0, received=[], M=0 - it ('should add messaging event handlers', ()=>{ - srv.on('reviewed', (msg)=> received.push(msg)) - }) - - it ('should add more messaging event handlers', ()=>{ - srv.on('reviewed', ()=> ++M) - }) - - it ('should add review', async ()=>{ - const review = { - ID: 111 + (++N), // FIXME: why does the generic handler not fill this in automatically ?!? --> it does so when the request comes in via Postman / OData - subject: "201", title: "Captivating", rating: N - } - const response = await srv.create ('Reviews') .entries (review) - expect (response) .toMatchObject (review) - },100) - - it ('should add more reviews', ()=> Promise.all ([ - // REVISIT: mass operation should trigger one message per entry - // srv.create('Reviews').entries( - // { ID: 111 + (++N), subject: "201", title: "Captivating", rating: N }, - // { ID: 111 + (++N), subject: "201", title: "Captivating", rating: N }, - // { ID: 111 + (++N), subject: "201", title: "Captivating", rating: N }, - // { ID: 111 + (++N), subject: "201", title: "Captivating", rating: N }, - // ), - srv.create ('Reviews') .entries ( - { ID: 111 + (++N), subject: "201", title: "Captivating", rating: N } - ), - srv.create ('Reviews') .entries ( - { ID: 111 + (++N), subject: "201", title: "Captivating", rating: N } - ), - srv.create ('Reviews') .entries ( - { ID: 111 + (++N), subject: "201", title: "Captivating", rating: N } - ), - srv.create ('Reviews') .entries ( - { ID: 111 + (++N), subject: "201", title: "Captivating", rating: N } - ), - ]) ,100) - - it ('should have received all messages', async()=> { - await new Promise((done)=>setImmediate(done)) - expect(M).toBe(N) - expect(received.length).toBe(N) - expect(received.map(m=>m.data)).toEqual([ - { subject: '201', rating: 1 }, - { subject: '201', rating: 1.5 }, - { subject: '201', rating: 2 }, - { subject: '201', rating: 2.5 }, - { subject: '201', rating: 3 }, - ]) - }) -}) diff --git a/packages/users-service/index.cds b/packages/users-service/index.cds deleted file mode 100644 index 8b17f004..00000000 --- a/packages/users-service/index.cds +++ /dev/null @@ -1 +0,0 @@ -using from './srv/services'; diff --git a/packages/users-service/package.json b/packages/users-service/package.json deleted file mode 100644 index e3f995b4..00000000 --- a/packages/users-service/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "@sap/capire-users", - "version": "1.0.0", - "description": "A reuse service for users-related functions, like registration, user profile mgmt, etc.", - "repository": "https://github.com/SAP-samples/cloud-cap-samples.git", - "license": "SAP SAMPLE CODE LICENSE", - "dependencies": { - "@sap/capire-contacts": "^1.0.0", - "@sap/cds": "latest", - "express": "*" - } -} diff --git a/packages/users-service/srv/services.cds b/packages/users-service/srv/services.cds deleted file mode 100644 index 05e5b9ac..00000000 --- a/packages/users-service/srv/services.cds +++ /dev/null @@ -1,7 +0,0 @@ -using { sap.capire.contacts.Contacts as RegisteredUsers } from '@sap/capire-contacts'; -namespace sap.capire.users; - -service UsersService @(requires:'authenticated-user') { - entity MyProfile as select from RegisteredUsers; - action login (); -} \ No newline at end of file