con <- dbConnect(RSQLite::SQLite(), "OrdersDB.sqlitedb.db")
Q1: What are the names and phone numbers of all shippers, sorted by
name?
SELECT ShipperName, Phone
FROM Shippers
ORDER BY ShipperName
LIMIT 10
Q2: What are the number of customers for each country? List the
country and the number of customers renamed to ‘NumCust’.
SELECT Country, COUNT(CUSTOMERID) AS NumCust
FROM Customers
GROUP BY Country
LIMIT 10
Q3: List the number of products by supplier ID and name, ordered
from most to least, restricted to those suppliers who sell at least five
products.
SELECT s.SupplierID, s.SupplierName, COUNT(p.Productname) AS NumProducts
FROM Suppliers s
JOIN Products p ON (s.SupplierID = p.SupplierID)
GROUP BY s.SupplierID,s.SupplierName
HAVING COUNT(p.Productname) >= 5
ORDER BY NumProducts DESC
Q5: What are the total number of unique orders delivered by each
shipper, ordered alphabetically by shipper name?
SELECT s.ShipperName, COUNT(DISTINCT o.OrderID) AS NumOrders
FROM Shippers s
JOIN Orders o ON (s.ShipperID = o.ShipperID)
GROUP BY s.ShipperName
ORDER BY s.ShipperName
LIMIT 10
Q6: How many employees never worked with a single customer, i.e.,
they appear in the Employees table but not in the Orders table?
SELECT COUNT(e.EmployeeID) AS NumEmployees
FROM Employees e
LEFT JOIN Orders o ON e.EmployeeID = o.EmployeeID
WHERE o.EmployeeID IS NULL
Q7: How many products contain “Louisiana” at the beginning of the
name of the product?
SELECT COUNT(ProductID) as NumProducts
FROM Products
WHERE Productname LIKE "Louisiana%"
Q8: What is the total number of distinct countries to which at least
one order was shipped?
SELECT COUNT(DISTINCT c.Country) AS NumCountries
FROM Orders o
JOIN Customers c ON o.CustomerID = c.CustomerID
Q9: What is the total amount (in terms of revenue) as well as the
total number of orders sold by each employee? List the employee name,
the total amount sold, and the total number of orders.
SELECT e.FirstName || ' ' || e.LastName AS EmployeeName,
SUM(p.Price * od.Quantity) AS TotalAmount,
COUNT(DISTINCT o.OrderID) AS TotalOrders
FROM Employees e
JOIN Orders o ON e.EmployeeID = o.EmployeeID
JOIN OrderDetails od ON o.OrderID = od.OrderID
JOIN Products p ON od.ProductID = p.ProductID
GROUP BY e.EmployeeID, e.LastName, e.FirstName
LIMIT 10
Q10: Which supplier sells the least number of different products but
supplies at least one product?
SELECT s.SupplierID, s.SupplierName, COUNT(DISTINCT p.ProductID) AS NumProducts
FROM Suppliers s
JOIN Products p ON s.SupplierID = p.SupplierID
GROUP BY s.SupplierID, s.SupplierName
HAVING NumProducts = (
SELECT MIN(cnt)
FROM (
SELECT COUNT(DISTINCT ProductID) AS cnt
FROM Products
GROUP BY SupplierID
)
)
Q11: Which product was ordered most often in terms of quantity
ordered? List the product name and ID.
SELECT p.ProductID, p.ProductName, SUM(o.Quantity) AS TotalQuantity
FROM OrderDetails o
JOIN Products p ON o.ProductID = p.ProductID
GROUP BY p.ProductID, p.ProductName
ORDER BY TotalQuantity DESC
LIMIT 1
Q12: Which product generated the most revenue? List the product ID
and name.
SELECT p.ProductID, p.Productname, SUM(o.Quantity * p.Price) AS Revenue
FROM Products p
JOIN OrderDetails o ON (p.ProductID = o.ProductID)
GROUP BY p.ProductID, p.Productname
ORDER BY Revenue DESC
LIMIT 1
Q13: What is the total amount spent by all customers who do live in
either Brazil, Mexico, or Canada?
SELECT SUM(od.Quantity * p.Price) AS TotalAmount
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID
JOIN OrderDetails od ON o.OrderID = od.OrderID
JOIN Products p ON od.ProductID = p.ProductID
WHERE c.Country IN ('Brazil', 'Mexico', 'Canada')
Q14: What is the difference in spending between the country to which
the most was sold versus the country to which the least was sold?
SELECT MAX(TotalAmount) - MIN(TotalAmount) AS DIFFERENCE
FROM (
SELECT c.Country, SUM(od.Quantity * p.Price) AS TotalAmount
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID
JOIN OrderDetails od ON o.OrderID = od.OrderID
JOIN Products p ON od.ProductID = p.ProductID
GROUP BY c.country
)
Q15: Which country has the least number of customers?
SELECT Country, COUNT(CustomerID) AS NumCustomers
FROM Customers
GROUP BY Country
ORDER BY NumCustomers ASC
LIMIT 1
Q16: Which employee generated the most revenue (in terms of “dollar
amount” sold)?
SELECT e.EmployeeID, e.LastName, e.FirstName, SUM(p.Price * od.Quantity) AS DollarAmount
FROM Employees e
JOIN Orders o ON e.EmployeeID = o.EmployeeID
JOIN OrderDetails od ON o.OrderID = od.OrderID
JOIN Products p ON od.ProductID = p.ProductID
GROUP BY e.EmployeeID, e.LastName, e.FirstName
ORDER BY DollarAmount DESC
LIMIT 1
Q17: Which customers (name and ID) have never bought anything?
SELECT c.CustomerID, c.CustomerName
FROM Customers c
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID
WHERE o.OrderID IS NULL
LIMIT 10
Q18: What is the average order total per country? List the country
and the average order total.
SELECT c.Country, AVG(OrderTotal) AS AvgOrderTotal
FROM (
SELECT o.OrderID, o.CustomerID, SUM(p.Price * od.Quantity) AS OrderTotal
FROM Orders o
JOIN OrderDetails od ON o.OrderID = od.OrderID
JOIN Products p ON od.ProductID = p.ProductID
GROUP BY o.OrderID, o.CustomerID
) sub
JOIN Customers c ON sub.CustomerID = c.CustomerID
GROUP BY c.Country
LIMIT 10
Q19: To which customer was the second most recent order sent? List
the Order ID, customer name, and country to which the order was
shipped.
SELECT o.OrderID, c.CustomerName, c.Country, o.OrderDate
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID
ORDER BY o.OrderDate DESC
LIMIT 1
OFFSET 1
Q20: From how many different (unique) suppliers do the products come
from that have been ordered at least five times?
SELECT COUNT(DISTINCT p.SupplierID) AS NumSuppliers
FROM Products p
WHERE p.ProductID IN (
SELECT od.ProductID
FROM OrderDetails od
GROUP BY od.ProductID
HAVING SUM(od.Quantity) >= 5
)
dbDisconnect(con)
LS0tCnRpdGxlOiAiQVNTSUdOTUVOVCAwNi4xOiBRdWVyeSBhIERhdGFiYXNlIHdpdGggU1FMIgphdXRob3I6ICJXYW5pLCBSdXNoaWtlc2giCmRhdGU6ICIyMDI2LTAyLTE0IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShEQkkpCmxpYnJhcnkoUlNRTGl0ZSkKYGBgCgpgYGB7ciBjb25uZWN0aW9ufQpjb24gPC0gZGJDb25uZWN0KFJTUUxpdGU6OlNRTGl0ZSgpLCAiT3JkZXJzREIuc3FsaXRlZGIuZGIiKQpgYGAKCiMjIyBRMTogV2hhdCBhcmUgdGhlIG5hbWVzIGFuZCBwaG9uZSBudW1iZXJzIG9mIGFsbCBzaGlwcGVycywgc29ydGVkIGJ5IG5hbWU/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgU2hpcHBlck5hbWUsIFBob25lIApGUk9NIFNoaXBwZXJzIApPUkRFUiBCWSBTaGlwcGVyTmFtZSAKTElNSVQgMTAgCmBgYAoKIyMjIFEyOiBXaGF0IGFyZSB0aGUgbnVtYmVyIG9mIGN1c3RvbWVycyBmb3IgZWFjaCBjb3VudHJ5PyBMaXN0IHRoZSBjb3VudHJ5IGFuZCB0aGUgbnVtYmVyIG9mIGN1c3RvbWVycyByZW5hbWVkIHRvICdOdW1DdXN0Jy4KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBDb3VudHJ5LCBDT1VOVChDVVNUT01FUklEKSBBUyBOdW1DdXN0IApGUk9NIEN1c3RvbWVycyAKR1JPVVAgQlkgQ291bnRyeSAKTElNSVQgMTAKYGBgCgojIyMgUTM6IExpc3QgdGhlIG51bWJlciBvZiBwcm9kdWN0cyBieSBzdXBwbGllciBJRCBhbmQgbmFtZSwgb3JkZXJlZCBmcm9tIG1vc3QgdG8gbGVhc3QsIHJlc3RyaWN0ZWQgdG8gdGhvc2Ugc3VwcGxpZXJzIHdobyBzZWxsIGF0IGxlYXN0IGZpdmUgcHJvZHVjdHMuCgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1Qgcy5TdXBwbGllcklELCBzLlN1cHBsaWVyTmFtZSwgQ09VTlQocC5Qcm9kdWN0bmFtZSkgQVMgTnVtUHJvZHVjdHMgCkZST00gU3VwcGxpZXJzIHMgCkpPSU4gUHJvZHVjdHMgcCBPTiAocy5TdXBwbGllcklEID0gcC5TdXBwbGllcklEKSAKR1JPVVAgQlkgcy5TdXBwbGllcklELHMuU3VwcGxpZXJOYW1lIApIQVZJTkcgQ09VTlQocC5Qcm9kdWN0bmFtZSkgPj0gNSAKT1JERVIgQlkgTnVtUHJvZHVjdHMgREVTQwpgYGAKCiMjIyBRNDogV2hvIHBsYWNlZCB0aGUgbW9zdCByZWNlbnQgb3JkZXIgKGJ5IG9yZGVyIGRhdGUpPyBMaXN0IHRoZSBjdXN0b21lcidzIElELCBjdXN0b21lciBuYW1lLCBjb250YWN0IG5hbWUsIGFuZCBkYXRlLgoKYGBge3NxbCBjb25uZWN0aW9uPWNvbn0KU0VMRUNUIGMuQ3VzdG9tZXJJRCwgYy5DdXN0b21lck5hbWUsIGMuQ29udGFjdE5hbWUsIG8ub3JkZXJEYXRlCkZST00gQ3VzdG9tZXJzIGMKSk9JTiBPcmRlcnMgbyBPTiAoYy5DdXN0b21lcklEID0gby5DdXN0b21lcklEKQpPUkRFUiBCWSBvLk9yZGVyRGF0ZSBERVNDCkxJTUlUIDEKYGBgCgojIyMgUTU6IFdoYXQgYXJlIHRoZSB0b3RhbCBudW1iZXIgb2YgdW5pcXVlIG9yZGVycyBkZWxpdmVyZWQgYnkgZWFjaCBzaGlwcGVyLCBvcmRlcmVkIGFscGhhYmV0aWNhbGx5IGJ5IHNoaXBwZXIgbmFtZT8KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBzLlNoaXBwZXJOYW1lLCBDT1VOVChESVNUSU5DVCBvLk9yZGVySUQpIEFTIE51bU9yZGVycwpGUk9NIFNoaXBwZXJzIHMKSk9JTiBPcmRlcnMgbyBPTiAocy5TaGlwcGVySUQgPSBvLlNoaXBwZXJJRCkKR1JPVVAgQlkgcy5TaGlwcGVyTmFtZSAKT1JERVIgQlkgcy5TaGlwcGVyTmFtZSAKTElNSVQgMTAKYGBgCgojIyMgUTY6IEhvdyBtYW55IGVtcGxveWVlcyBuZXZlciB3b3JrZWQgd2l0aCBhIHNpbmdsZSBjdXN0b21lciwgaS5lLiwgdGhleSBhcHBlYXIgaW4gdGhlIEVtcGxveWVlcyB0YWJsZSBidXQgbm90IGluIHRoZSBPcmRlcnMgdGFibGU/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgQ09VTlQoZS5FbXBsb3llZUlEKSBBUyBOdW1FbXBsb3llZXMKRlJPTSBFbXBsb3llZXMgZQpMRUZUIEpPSU4gT3JkZXJzIG8gT04gZS5FbXBsb3llZUlEID0gby5FbXBsb3llZUlECldIRVJFIG8uRW1wbG95ZWVJRCBJUyBOVUxMCmBgYAoKIyMjIFE3OiBIb3cgbWFueSBwcm9kdWN0cyBjb250YWluICJMb3Vpc2lhbmEiIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3Q/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgQ09VTlQoUHJvZHVjdElEKSBhcyBOdW1Qcm9kdWN0cwpGUk9NIFByb2R1Y3RzCldIRVJFIFByb2R1Y3RuYW1lIExJS0UgIkxvdWlzaWFuYSUiCmBgYAoKIyMjIFE4OiBXaGF0IGlzIHRoZSB0b3RhbCBudW1iZXIgb2YgZGlzdGluY3QgY291bnRyaWVzIHRvIHdoaWNoIGF0IGxlYXN0IG9uZSBvcmRlciB3YXMgc2hpcHBlZD8KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBDT1VOVChESVNUSU5DVCBjLkNvdW50cnkpIEFTIE51bUNvdW50cmllcwpGUk9NIE9yZGVycyBvCkpPSU4gQ3VzdG9tZXJzIGMgT04gby5DdXN0b21lcklEID0gYy5DdXN0b21lcklECmBgYAoKIyMjIFE5OiBXaGF0IGlzIHRoZSB0b3RhbCBhbW91bnQgKGluIHRlcm1zIG9mIHJldmVudWUpIGFzIHdlbGwgYXMgdGhlIHRvdGFsIG51bWJlciBvZiBvcmRlcnMgc29sZCBieSBlYWNoIGVtcGxveWVlPyBMaXN0IHRoZSBlbXBsb3llZSBuYW1lLCB0aGUgdG90YWwgYW1vdW50IHNvbGQsIGFuZCB0aGUgdG90YWwgbnVtYmVyIG9mIG9yZGVycy4KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBlLkZpcnN0TmFtZSB8fCAnICcgfHwgZS5MYXN0TmFtZSBBUyBFbXBsb3llZU5hbWUsCiAgICAgICBTVU0ocC5QcmljZSAqIG9kLlF1YW50aXR5KSBBUyBUb3RhbEFtb3VudCwKICAgICAgIENPVU5UKERJU1RJTkNUIG8uT3JkZXJJRCkgQVMgVG90YWxPcmRlcnMKRlJPTSBFbXBsb3llZXMgZQpKT0lOIE9yZGVycyBvIE9OIGUuRW1wbG95ZWVJRCA9IG8uRW1wbG95ZWVJRApKT0lOIE9yZGVyRGV0YWlscyBvZCBPTiBvLk9yZGVySUQgPSBvZC5PcmRlcklECkpPSU4gUHJvZHVjdHMgcCBPTiBvZC5Qcm9kdWN0SUQgPSBwLlByb2R1Y3RJRApHUk9VUCBCWSBlLkVtcGxveWVlSUQsIGUuTGFzdE5hbWUsIGUuRmlyc3ROYW1lCkxJTUlUIDEwCmBgYAoKIyMjIFExMDogV2hpY2ggc3VwcGxpZXIgc2VsbHMgdGhlIGxlYXN0IG51bWJlciBvZiBkaWZmZXJlbnQgcHJvZHVjdHMgYnV0IHN1cHBsaWVzIGF0IGxlYXN0IG9uZSBwcm9kdWN0PwoKYGBge3NxbCBjb25uZWN0aW9uPWNvbn0KU0VMRUNUIHMuU3VwcGxpZXJJRCwgcy5TdXBwbGllck5hbWUsIENPVU5UKERJU1RJTkNUIHAuUHJvZHVjdElEKSBBUyBOdW1Qcm9kdWN0cwpGUk9NIFN1cHBsaWVycyBzCkpPSU4gUHJvZHVjdHMgcCBPTiBzLlN1cHBsaWVySUQgPSBwLlN1cHBsaWVySUQKR1JPVVAgQlkgcy5TdXBwbGllcklELCBzLlN1cHBsaWVyTmFtZQpIQVZJTkcgTnVtUHJvZHVjdHMgPSAoCiAgICBTRUxFQ1QgTUlOKGNudCkgCiAgICBGUk9NICgKICAgICAgICBTRUxFQ1QgQ09VTlQoRElTVElOQ1QgUHJvZHVjdElEKSBBUyBjbnQgCiAgICAgICAgRlJPTSBQcm9kdWN0cyAKICAgICAgICBHUk9VUCBCWSBTdXBwbGllcklECiAgICApCikKYGBgCgojIyMgUTExOiBXaGljaCBwcm9kdWN0IHdhcyBvcmRlcmVkIG1vc3Qgb2Z0ZW4gaW4gdGVybXMgb2YgcXVhbnRpdHkgb3JkZXJlZD8gTGlzdCB0aGUgcHJvZHVjdCBuYW1lIGFuZCBJRC4KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBwLlByb2R1Y3RJRCwgcC5Qcm9kdWN0TmFtZSwgU1VNKG8uUXVhbnRpdHkpIEFTIFRvdGFsUXVhbnRpdHkKRlJPTSBPcmRlckRldGFpbHMgbwpKT0lOIFByb2R1Y3RzIHAgT04gby5Qcm9kdWN0SUQgPSBwLlByb2R1Y3RJRApHUk9VUCBCWSBwLlByb2R1Y3RJRCwgcC5Qcm9kdWN0TmFtZQpPUkRFUiBCWSBUb3RhbFF1YW50aXR5IERFU0MKTElNSVQgMQpgYGAKCiMjIyBRMTI6IFdoaWNoIHByb2R1Y3QgZ2VuZXJhdGVkIHRoZSBtb3N0IHJldmVudWU/IExpc3QgdGhlIHByb2R1Y3QgSUQgYW5kIG5hbWUuCgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgcC5Qcm9kdWN0SUQsIHAuUHJvZHVjdG5hbWUsIFNVTShvLlF1YW50aXR5ICogcC5QcmljZSkgIEFTIFJldmVudWUKRlJPTSBQcm9kdWN0cyBwCkpPSU4gT3JkZXJEZXRhaWxzIG8gT04gKHAuUHJvZHVjdElEID0gby5Qcm9kdWN0SUQpCkdST1VQIEJZIHAuUHJvZHVjdElELCBwLlByb2R1Y3RuYW1lCk9SREVSIEJZIFJldmVudWUgREVTQwpMSU1JVCAxCmBgYAoKIyMjIFExMzogV2hhdCBpcyB0aGUgdG90YWwgYW1vdW50IHNwZW50IGJ5IGFsbCBjdXN0b21lcnMgd2hvIGRvIGxpdmUgaW4gZWl0aGVyIEJyYXppbCwgTWV4aWNvLCBvciBDYW5hZGE/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgU1VNKG9kLlF1YW50aXR5ICogcC5QcmljZSkgQVMgVG90YWxBbW91bnQKRlJPTSBDdXN0b21lcnMgYwpKT0lOIE9yZGVycyBvIE9OIGMuQ3VzdG9tZXJJRCA9IG8uQ3VzdG9tZXJJRApKT0lOIE9yZGVyRGV0YWlscyBvZCBPTiBvLk9yZGVySUQgPSBvZC5PcmRlcklECkpPSU4gUHJvZHVjdHMgcCBPTiBvZC5Qcm9kdWN0SUQgPSBwLlByb2R1Y3RJRApXSEVSRSBjLkNvdW50cnkgSU4gKCdCcmF6aWwnLCAnTWV4aWNvJywgJ0NhbmFkYScpCmBgYAoKIyMjIFExNDogV2hhdCBpcyB0aGUgZGlmZmVyZW5jZSBpbiBzcGVuZGluZyBiZXR3ZWVuIHRoZSBjb3VudHJ5IHRvIHdoaWNoIHRoZSBtb3N0IHdhcyBzb2xkIHZlcnN1cyB0aGUgY291bnRyeSB0byB3aGljaCB0aGUgbGVhc3Qgd2FzIHNvbGQ/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgTUFYKFRvdGFsQW1vdW50KSAtIE1JTihUb3RhbEFtb3VudCkgQVMgRElGRkVSRU5DRQpGUk9NICgKICAgICAgU0VMRUNUIGMuQ291bnRyeSwgU1VNKG9kLlF1YW50aXR5ICogcC5QcmljZSkgQVMgVG90YWxBbW91bnQKICAgICAgRlJPTSBDdXN0b21lcnMgYwogICAgICBKT0lOIE9yZGVycyBvIE9OIGMuQ3VzdG9tZXJJRCA9IG8uQ3VzdG9tZXJJRAogICAgICBKT0lOIE9yZGVyRGV0YWlscyBvZCBPTiBvLk9yZGVySUQgPSBvZC5PcmRlcklECiAgICAgIEpPSU4gUHJvZHVjdHMgcCBPTiBvZC5Qcm9kdWN0SUQgPSBwLlByb2R1Y3RJRAogICAgICBHUk9VUCBCWSBjLmNvdW50cnkKKQpgYGAKCiMjIyBRMTU6IFdoaWNoIGNvdW50cnkgaGFzIHRoZSBsZWFzdCBudW1iZXIgb2YgY3VzdG9tZXJzPwoKYGBge3NxbCBjb25uZWN0aW9uPWNvbn0KU0VMRUNUIENvdW50cnksIENPVU5UKEN1c3RvbWVySUQpIEFTIE51bUN1c3RvbWVycwpGUk9NIEN1c3RvbWVycwpHUk9VUCBCWSBDb3VudHJ5Ck9SREVSIEJZIE51bUN1c3RvbWVycyBBU0MKTElNSVQgMQpgYGAKCiMjIyBRMTY6IFdoaWNoIGVtcGxveWVlIGdlbmVyYXRlZCB0aGUgbW9zdCByZXZlbnVlIChpbiB0ZXJtcyBvZiAiZG9sbGFyIGFtb3VudCIgc29sZCk/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgZS5FbXBsb3llZUlELCBlLkxhc3ROYW1lLCBlLkZpcnN0TmFtZSwgU1VNKHAuUHJpY2UgKiBvZC5RdWFudGl0eSkgQVMgRG9sbGFyQW1vdW50CkZST00gRW1wbG95ZWVzIGUKSk9JTiBPcmRlcnMgbyBPTiBlLkVtcGxveWVlSUQgPSBvLkVtcGxveWVlSUQKSk9JTiBPcmRlckRldGFpbHMgb2QgT04gby5PcmRlcklEID0gb2QuT3JkZXJJRApKT0lOIFByb2R1Y3RzIHAgT04gb2QuUHJvZHVjdElEID0gcC5Qcm9kdWN0SUQKR1JPVVAgQlkgZS5FbXBsb3llZUlELCBlLkxhc3ROYW1lLCBlLkZpcnN0TmFtZQpPUkRFUiBCWSBEb2xsYXJBbW91bnQgREVTQwpMSU1JVCAxCmBgYAoKIyMjIFExNzogV2hpY2ggY3VzdG9tZXJzIChuYW1lIGFuZCBJRCkgaGF2ZSBuZXZlciBib3VnaHQgYW55dGhpbmc/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgYy5DdXN0b21lcklELCBjLkN1c3RvbWVyTmFtZQpGUk9NIEN1c3RvbWVycyBjCkxFRlQgSk9JTiBPcmRlcnMgbyBPTiBjLkN1c3RvbWVySUQgPSBvLkN1c3RvbWVySUQKV0hFUkUgby5PcmRlcklEIElTIE5VTEwgCkxJTUlUIDEwCmBgYAoKIyMjIFExODogV2hhdCBpcyB0aGUgYXZlcmFnZSBvcmRlciB0b3RhbCBwZXIgY291bnRyeT8gTGlzdCB0aGUgY291bnRyeSBhbmQgdGhlIGF2ZXJhZ2Ugb3JkZXIgdG90YWwuCgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgYy5Db3VudHJ5LCBBVkcoT3JkZXJUb3RhbCkgQVMgQXZnT3JkZXJUb3RhbApGUk9NICgKICAgIFNFTEVDVCBvLk9yZGVySUQsIG8uQ3VzdG9tZXJJRCwgU1VNKHAuUHJpY2UgKiBvZC5RdWFudGl0eSkgQVMgT3JkZXJUb3RhbAogICAgRlJPTSBPcmRlcnMgbwogICAgSk9JTiBPcmRlckRldGFpbHMgb2QgT04gby5PcmRlcklEID0gb2QuT3JkZXJJRAogICAgSk9JTiBQcm9kdWN0cyBwIE9OIG9kLlByb2R1Y3RJRCA9IHAuUHJvZHVjdElECiAgICBHUk9VUCBCWSBvLk9yZGVySUQsIG8uQ3VzdG9tZXJJRAopIHN1YgpKT0lOIEN1c3RvbWVycyBjIE9OIHN1Yi5DdXN0b21lcklEID0gYy5DdXN0b21lcklECkdST1VQIEJZIGMuQ291bnRyeQpMSU1JVCAxMApgYGAKCiMjIyBRMTk6IFRvIHdoaWNoIGN1c3RvbWVyIHdhcyB0aGUgc2Vjb25kIG1vc3QgcmVjZW50IG9yZGVyIHNlbnQ/IExpc3QgdGhlIE9yZGVyIElELCBjdXN0b21lciBuYW1lLCBhbmQgY291bnRyeSB0byB3aGljaCB0aGUgb3JkZXIgd2FzIHNoaXBwZWQuCgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1Qgby5PcmRlcklELCBjLkN1c3RvbWVyTmFtZSwgYy5Db3VudHJ5LCBvLk9yZGVyRGF0ZQpGUk9NIEN1c3RvbWVycyBjCkpPSU4gT3JkZXJzIG8gT04gYy5DdXN0b21lcklEID0gby5DdXN0b21lcklECk9SREVSIEJZIG8uT3JkZXJEYXRlIERFU0MKTElNSVQgMQpPRkZTRVQgMQpgYGAKCiMjIyBRMjA6IEZyb20gaG93IG1hbnkgZGlmZmVyZW50ICh1bmlxdWUpIHN1cHBsaWVycyBkbyB0aGUgcHJvZHVjdHMgY29tZSBmcm9tIHRoYXQgaGF2ZSBiZWVuIG9yZGVyZWQgYXQgbGVhc3QgZml2ZSB0aW1lcz8KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBDT1VOVChESVNUSU5DVCBwLlN1cHBsaWVySUQpIEFTIE51bVN1cHBsaWVycwpGUk9NIFByb2R1Y3RzIHAKV0hFUkUgcC5Qcm9kdWN0SUQgSU4gKAogICAgU0VMRUNUIG9kLlByb2R1Y3RJRAogICAgRlJPTSBPcmRlckRldGFpbHMgb2QKICAgIEdST1VQIEJZIG9kLlByb2R1Y3RJRAogICAgSEFWSU5HIFNVTShvZC5RdWFudGl0eSkgPj0gNQopCmBgYAoKYGBge3IgZGlzY29ubmVjdH0KZGJEaXNjb25uZWN0KGNvbikKYGBgCg==