CREATE DATABASE IF NOT EXISTS glasses_shop_db
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE glasses_shop_db;
DROP TABLE IF EXISTS Product_Discount;
DROP TABLE IF EXISTS Comments;
DROP TABLE IF EXISTS Product_Order;
DROP TABLE IF EXISTS Orders;
DROP TABLE IF EXISTS User_Address;
DROP TABLE IF EXISTS User_Role;
DROP TABLE IF EXISTS Products;
DROP TABLE IF EXISTS Users;
DROP TABLE IF EXISTS Vouchers;
DROP TABLE IF EXISTS Discounts;
DROP TABLE IF EXISTS Address;
DROP TABLE IF EXISTS Categories;
DROP TABLE IF EXISTS Brands;
DROP TABLE IF EXISTS Roles;
-- 1 . B ảng Vai trò
CREATE TABLE Roles (
role_id INT PRIMARY KEY AUTO_INCREMENT,
role_name VARCHAR( 255 ) NOT NULL UNIQUE
) ;
-- 2 . B ảng Thương hiệu
CREATE TABLE Brands (
brand_id INT PRIMARY KEY AUTO_INCREMENT,
brand_name VARCHAR( 255 ) NOT NULL,
description VARCHAR( 255 )
) ;
-- 3 . B ảng Danh mục sản phẩm
CREATE TABLE Categories (
category_id INT PRIMARY KEY AUTO_INCREMENT,
category_name VARCHAR( 255 ) NOT NULL
) ;
-- 4 . B ảng Địa chỉ ( Dùng chung)
CREATE TABLE Address (
address_id INT PRIMARY KEY AUTO_INCREMENT,
city VARCHAR( 255 ) NOT NULL,
street VARCHAR( 255 ) NOT NULL,
specifiable_address VARCHAR( 255 )
) ;
-- 5 . B ảng Giảm giá
CREATE TABLE Discounts (
discount_id INT PRIMARY KEY AUTO_INCREMENT,
discount_percent INT NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
is_active INT DEFAULT 1
) ;
-- 6 . B ảng Voucher
CREATE TABLE Vouchers (
voucher_id INT PRIMARY KEY AUTO_INCREMENT,
discount_type INT NOT NULL, -- 1 : %, 2 : tiền mặt
discount_value INT NOT NULL,
min_order_value INT NOT NULL,
max_discount_amount INT,
usage_limit INT,
used_count INT DEFAULT 0 ,
expiry_date DATE NOT NULL
) ;
-- 7 . B ảng Người dùng
CREATE TABLE Users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
user_name VARCHAR( 255 ) NOT NULL UNIQUE,
password_hash VARCHAR( 255 ) NOT NULL,
full_name VARCHAR( 255 ) NOT NULL,
email VARCHAR( 255 ) NOT NULL UNIQUE,
phone_number VARCHAR( 20 )
) ;
-- 8 . B ảng Sản phẩm
CREATE TABLE Products (
product_id INT PRIMARY KEY AUTO_INCREMENT,
category_id INT,
brand_id INT,
product_name VARCHAR( 255 ) NOT NULL,
material VARCHAR( 255 ) ,
shape VARCHAR( 255 ) ,
base_price INT NOT NULL,
stock_quantity INT DEFAULT 0 ,
description TEXT,
FOREIGN KEY ( category_id) REFERENCES Categories( category_id) ,
FOREIGN KEY ( brand_id) REFERENCES Brands( brand_id)
) ;
-- 9 . Li ên kết User - Role ( N- N)
CREATE TABLE User_Role (
user_id INT,
role_id INT,
PRIMARY KEY ( user_id, role_id) ,
FOREIGN KEY ( user_id) REFERENCES Users( user_id) ON DELETE CASCADE,
FOREIGN KEY ( role_id) REFERENCES Roles( role_id) ON DELETE CASCADE
) ;
-- 10 . Li ên kết User - Address ( N- N)
CREATE TABLE User_Address (
user_id INT,
address_id INT,
PRIMARY KEY ( user_id, address_id) ,
FOREIGN KEY ( user_id) REFERENCES Users( user_id) ON DELETE CASCADE,
FOREIGN KEY ( address_id) REFERENCES Address( address_id) ON DELETE CASCADE
) ;
-- 11 . Đơn hàng
CREATE TABLE Orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
address_id INT,
voucher_id INT,
total_price INT NOT NULL,
discount_amount INT DEFAULT 0 ,
status VARCHAR( 20 ) DEFAULT 'Pending' ,
order_date DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY ( user_id) REFERENCES Users( user_id) ,
FOREIGN KEY ( address_id) REFERENCES Address( address_id) ,
FOREIGN KEY ( voucher_id) REFERENCES Vouchers( voucher_id)
) ;
-- 12 . Chi tiết đơn hàng ( N- N giữa Product và Order)
CREATE TABLE Product_Order (
product_id INT,
order_id INT,
price_at_purchase INT NOT NULL,
quantity INT NOT NULL,
PRIMARY KEY ( product_id, order_id) ,
FOREIGN KEY ( product_id) REFERENCES Products( product_id) ,
FOREIGN KEY ( order_id) REFERENCES Orders( order_id) ON DELETE CASCADE
) ;
-- 13 . Comment & Đánh giá
CREATE TABLE Comments (
comment_id INT PRIMARY KEY AUTO_INCREMENT,
product_id INT,
order_id INT,
rate INT CHECK ( rate BETWEEN 1 AND 5 ) ,
description TEXT,
FOREIGN KEY ( product_id) REFERENCES Products( product_id) ,
FOREIGN KEY ( order_id) REFERENCES Orders( order_id)
) ;
-- 14 . Li ên kết Product - Discount ( N- N)
CREATE TABLE Product_Discount (
product_id INT,
discount_id INT,
PRIMARY KEY ( product_id, discount_id) ,
FOREIGN KEY ( product_id) REFERENCES Products( product_id) ,
FOREIGN KEY ( discount_id) REFERENCES Discounts( discount_id)
) ;
-- ==========================================
-- PHẦN 3 : INSERT DỮ LIỆU MẪU ( SEED DATA - BẢN X3 DỮ LIỆU)
-- ==========================================
-- 1 . B ảng Roles ( 9 Vai trò)
INSERT INTO Roles ( role_name) VALUES
( 'ADMIN' ) ,
( 'CUSTOMER' ) ,
( 'STAFF' ) ,
( 'MANAGER' ) ,
( 'MARKETING' ) ,
( 'ACCOUNTANT' ) ,
( 'WAREHOUSE' ) ,
( 'SUPPORT' ) ,
( 'GUEST' ) ;
-- 2 . B ảng Brands ( 12 Thương hiệu)
INSERT INTO Brands ( brand_name, description) VALUES
( 'Ray-Ban' , 'Thương hiệu mắt kính huyền thoại từ Mỹ' ) ,
( 'Gucci' , 'Kính mắt thời trang cao cấp từ Ý' ) ,
( 'Gentle Monster' , 'Thương hiệu thời trang giới trẻ Hàn Quốc' ) ,
( 'Oakley' , 'Kính thể thao chuyên dụng' ) ,
( 'Dior' , 'Thời trang xa xỉ từ Pháp' ) ,
( 'Prada' , 'Phong cách thanh lịch và hiện đại' ) ,
( 'Tom Ford' , 'Sang trọng, đẳng cấp dành cho doanh nhân' ) ,
( 'Carrera' , 'Thiết kế nam tính, mạnh mẽ' ) ,
( 'Police' , 'Phong cách đường phố Ý' ) ,
( 'Lacoste' , 'Thanh lịch pha lẫn thể thao' ) ,
( 'Calvin Klein' , 'Tối giản, trẻ trung' ) ,
( 'Warby Parker' , 'Thương hiệu kính giá tốt chất lượng cao' ) ;
-- 3 . B ảng Categories ( 12 Danh mục)
INSERT INTO Categories ( category_name) VALUES
( 'Kính râm (Sunglasses)' ) ,
( 'Kính cận (Prescription Glasses)' ) ,
( 'Kính chống ánh sáng xanh' ) ,
( 'Kính thể thao' ) ,
( 'Kính viễn' ) ,
( 'Kính lão' ) ,
( 'Kính thời trang không độ' ) ,
( 'Kính bơi' ) ,
( 'Kính bảo hộ' ) ,
( 'Kính phân cực (Polarized)' ) ,
( 'Kính trẻ em' ) ,
( 'Gọng kính Titanium' ) ;
-- 4 . B ảng Address ( 12 Địa chỉ)
INSERT INTO Address ( city, street, specifiable_address) VALUES
( 'Hà Nội' , 'Cầu Giấy' , 'Số 10, ngõ 20' ) ,
( 'Hà Nội' , 'Hà Đông' , 'Ký túc xá PTIT' ) ,
( 'TP. Hồ Chí Minh' , 'Quận 1' , 'Tòa nhà Bitexco, số 2 Hải Triều' ) ,
( 'Đà Nẵng' , 'Hải Châu' , '15 Lê Duẩn' ) ,
( 'Hà Nội' , 'Đống Đa' , 'Số 5, ngõ Thái Hà' ) ,
( 'TP. Hồ Chí Minh' , 'Quận 7' , 'Khu đô thị Phú Mỹ Hưng' ) ,
( 'Hải Phòng' , 'Lê Chân' , '120 Tô Hiệu' ) ,
( 'Cần Thơ' , 'Ninh Kiều' , '36 Mậu Thân' ) ,
( 'Đà Lạt' , 'Phường 1' , 'Khu Hòa Bình' ) ,
( 'Nha Trang' , 'Lộc Thọ' , '78 Trần Phú' ) ,
( 'Huế' , 'Phú Nhuận' , '12 Lê Lợi' ) ,
( 'Đà Nẵng' , 'Sơn Trà' , 'Đường Phạm Văn Đồng' ) ;
-- 5 . B ảng Discounts ( 9 Giảm giá)
INSERT INTO Discounts ( discount_percent, start_date, end_date, is_active) VALUES
( 10 , '2026-01-01' , '2026-12-31' , 1 ) , -- Đang hoạt động
( 50 , '2025-01-01' , '2025-01-31' , 0 ) , -- Đã hết hạn
( 20 , '2026-04-01' , '2026-04-30' , 1 ) , -- Đang hoạt động tháng này
( 15 , '2026-05-01' , '2026-05-31' , 1 ) , -- Sắp diễn ra
( 5 , '2026-01-01' , '2026-12-31' , 1 ) , -- Giảm nhẹ
( 70 , '2025-11-20' , '2025-11-25' , 0 ) , -- Đã hết hạn ( Black Friday cũ)
( 25 , '2026-03-01' , '2026-03-31' , 0 ) , -- Vừa hết hạn
( 30 , '2026-06-01' , '2026-08-31' , 1 ) , -- Giảm giá mùa hè
( 12 , '2026-04-15' , '2026-04-20' , 1 ) ; -- Giảm giá chớp nhoáng ( Flash sale)
-- 6 . B ảng Vouchers ( 9 Voucher đa dạng)
INSERT INTO Vouchers ( discount_type, discount_value, min_order_value, max_discount_amount, usage_limit, used_count, expiry_date) VALUES
( 1 , 15 , 1000000 , 500000 , 100 , 10 , '2026-12-31' ) , -- Giảm 15 %
( 2 , 100000 , 500000 , 100000 , 50 , 5 , '2026-12-31' ) , -- Giảm 100k
( 1 , 10 , 0 , NULL, 500 , 500 , '2026-12-31' ) , -- Lỗi hết lượt dùng
( 2 , 50000 , 200000 , 50000 , 1000 , 120 , '2026-06-30' ) ,-- Voucher freeship giả lập
( 1 , 20 , 2000000 , 800000 , 20 , 0 , '2026-05-15' ) , -- Voucher giá trị cao, ít lượt
( 2 , 200000 , 1500000 , 200000 , 100 , 99 , '2026-12-31' ) ,-- Sắp hết lượt
( 1 , 5 , 0 , 50000 , 10000 , 450 , '2027-01-01' ) , -- Voucher phổ thông
( 2 , 500000 , 5000000 , 500000 , 10 , 10 , '2026-04-30' ) ,-- Đã hết lượt
( 1 , 50 , 0 , 100000 , 50 , 0 , '2025-12-31' ) ; -- Đã hết hạn sử dụng
-- 7 . B ảng Users ( 9 Người dùng)
INSERT INTO Users ( user_name, password_hash, full_name, email, phone_number) VALUES
( 'admin_root' , '$2a$12$DUMMYHASHFOR123456' , 'Quản Trị Viên' , 'admin@glassesshop.vn' , '0900000000' ) ,
( 'dev_tester' , '$2a$12$DUMMYHASHFOR123456' , 'Kỹ Sư Hệ Thống' , 'dev@gmail.com' , '0912345678' ) ,
( 'mai_nguyen' , '$2a$12$DUMMYHASHFOR123456' , 'Nguyễn Thị Mai' , 'mai.nguyen@yahoo.com' , '0987654321' ) ,
( 'hoang_nam' , '$2a$12$DUMMYHASHFOR123456' , 'Trần Hoàng Nam' , 'nam.tran@gmail.com' , '0933112233' ) ,
( 'linh_chi' , '$2a$12$DUMMYHASHFOR123456' , 'Lê Linh Chi' , 'chi.le@hotmail.com' , '0911223344' ) ,
( 'tuan_anh' , '$2a$12$DUMMYHASHFOR123456' , 'Phạm Tuấn Anh' , 'tuananh.pham@glassesshop.vn' , '0944556677' ) ,
( 'quynh_nhu' , '$2a$12$DUMMYHASHFOR123456' , 'Vũ Quỳnh Như' , 'nhu.vu@gmail.com' , '0966778899' ) ,
( 'quang_hai' , '$2a$12$DUMMYHASHFOR123456' , 'Nguyễn Quang Hải' , 'hai.nguyen@yahoo.com' , '0977889900' ) ,
( 'bao_tram' , '$2a$12$DUMMYHASHFOR123456' , 'Đỗ Bảo Trâm' , 'tram.do@gmail.com' , '0988990011' ) ;
-- 8 . B ảng Products ( 15 Sản phẩm đa dạng)
INSERT INTO Products ( category_id, brand_id, product_name, material, shape, base_price, stock_quantity, description) VALUES
( 1 , 1 , 'Ray-Ban Aviator Classic' , 'Kim loại' , 'Aviator' , 4500000 , 20 , 'Kính râm phi công màu xanh lục cổ điển' ) ,
( 2 , 2 , 'Gucci Square Optical' , 'Nhựa Acetate' , 'Vuông' , 8200000 , 5 , 'Gọng kính cận thời trang nam nữ cao cấp' ) ,
( 1 , 3 , 'Gentle Monster Lilit' , 'Nhựa Acetate' , 'Vuông bo góc' , 6500000 , 0 , 'Kính râm hot trend (Hết hàng)' ) ,
( 3 , 1 , 'Ray-Ban Clubmaster Blue-Light' , 'Hỗn hợp' , 'Clubmaster' , 3800000 , 30 , 'Mắt kính bảo vệ mắt' ) ,
( 4 , 4 , 'Oakley Radar EV Path' , 'Nhựa O Matter' , 'Thể thao' , 5500000 , 10 , 'Kính đạp xe chuyên nghiệp' ) ,
( 1 , 5 , 'DiorStellaire1' , 'Kim loại' , 'Vuông lớn' , 9500000 , 3 , 'Kính râm nữ thiết kế oversize sang trọng' ) ,
( 2 , 6 , 'Prada Minimal Baroque' , 'Nhựa' , 'Tròn' , 7800000 , 12 , 'Gọng kính cận họa tiết xoắn ốc độc đáo' ) ,
( 5 , 7 , 'Tom Ford FT5401' , 'Kim loại' , 'Chữ nhật' , 11000000 , 8 , 'Kính viễn cao cấp cho nam giới' ) ,
( 6 , 8 , 'Carrera 1005/S' , 'Hỗn hợp' , 'Phi công' , 4200000 , 25 , 'Kính râm nam tính mạnh mẽ' ) ,
( 10 , 9 , 'Police Origins 1' , 'Hợp kim' , 'Vuông' , 3600000 , 15 , 'Kính phân cực chống lóa khi lái xe' ) ,
( 7 , 10 , 'Lacoste L2767' , 'Nhựa dẻo' , 'Chữ nhật' , 2900000 , 50 , 'Kính thời trang không độ form gọn nhẹ' ) ,
( 11 , 1 , 'Ray-Ban Junior RJ9052S' , 'Nhựa an toàn' , 'Tròn' , 1800000 , 40 , 'Kính râm bảo vệ mắt cho trẻ em' ) ,
( 12 , 11 , 'CK Titanium Rimless' , 'Titanium' , 'Không viền' , 5200000 , 18 , 'Gọng kính siêu nhẹ tàng hình trên mặt' ) ,
( 8 , 4 , 'Oakley Swim Goggles' , 'Silicone' , 'Thể thao' , 1200000 , 60 , 'Kính bơi chống sương mù' ) ,
( 2 , 12 , 'Warby Parker Haskell' , 'Nhựa tái chế' , 'Tròn' , 2500000 , 0 , 'Gọng kính thân thiện môi trường (Đang đợi hàng về)' ) ;
-- 9 . B ảng User_Role ( 9 Liên kết)
INSERT INTO User_Role ( user_id, role_id) VALUES
( 1 , 1 ) , -- admin_root là ADMIN
( 2 , 2 ) , -- dev_tester là CUSTOMER
( 3 , 2 ) , -- mai_nguyen là CUSTOMER
( 4 , 2 ) , -- hoang_nam là CUSTOMER
( 5 , 2 ) , -- linh_chi là CUSTOMER
( 6 , 3 ) , -- tuan_anh là STAFF
( 7 , 4 ) , -- quynh_nhu là MANAGER
( 8 , 2 ) , -- quang_hai là CUSTOMER
( 9 , 2 ) ; -- bao_tram là CUSTOMER
-- 10 . B ảng User_Address ( 9 Liên kết)
INSERT INTO User_Address ( user_id, address_id) VALUES
( 1 , 1 ) ,
( 2 , 2 ) ,
( 3 , 3 ) ,
( 4 , 4 ) ,
( 5 , 5 ) ,
( 6 , 6 ) ,
( 7 , 7 ) ,
( 8 , 8 ) ,
( 9 , 9 ) ;
-- 11 . B ảng Product_Discount ( 6 Liên kết)
INSERT INTO Product_Discount ( product_id, discount_id) VALUES
( 3 , 3 ) , -- Gentle Monster được giảm 20 %
( 4 , 1 ) , -- Ray- Ban Blue- light giảm 10 %
( 8 , 5 ) , -- Tom Ford giảm 5 %
( 12 , 8 ) , -- Kính trẻ em giảm 30 % hè
( 1 , 2 ) , -- Hết hạn giảm giá
( 15 , 1 ) ; -- Warby Parker giảm 10 %
-- 12 . B ảng Orders ( 9 Đơn hàng đa dạng trạng thái)
INSERT INTO Orders ( user_id, address_id, voucher_id, total_price, discount_amount, status, order_date) VALUES
( 2 , 2 , 1 , 6500000 , 500000 , 'Completed' , '2026-04-10 10:00:00' ) ,
( 3 , 3 , NULL, 4500000 , 0 , 'Pending' , '2026-04-14 15:30:00' ) ,
( 2 , 2 , NULL, 8200000 , 0 , 'Cancelled' , '2026-04-12 08:00:00' ) ,
( 4 , 4 , 2 , 11000000 , 100000 , 'Processing' , '2026-04-15 09:00:00' ) ,
( 5 , 5 , 4 , 3800000 , 50000 , 'Shipping' , '2026-04-13 14:20:00' ) ,
( 8 , 8 , NULL, 9500000 , 0 , 'Completed' , '2026-03-20 11:15:00' ) ,
( 9 , 9 , 7 , 2900000 , 50000 , 'Pending' , '2026-04-15 10:30:00' ) ,
( 3 , 3 , NULL, 5400000 , 0 , 'Returned' , '2026-02-14 16:45:00' ) ,
( 4 , 4 , 5 , 15000000 , 800000 , 'Completed' , '2026-01-05 08:30:00' ) ;
-- 13 . B ảng Product_Order ( 14 Chi tiết sản phẩm trong đơn)
INSERT INTO Product_Order ( product_id, order_id, price_at_purchase, quantity) VALUES
( 3 , 1 , 6500000 , 1 ) , -- Đơn 1 mua Gentle Monster
( 1 , 2 , 4500000 , 1 ) , -- Đơn 2 mua Ray- Ban
( 2 , 3 , 8200000 , 1 ) , -- Đơn 3 mua Gucci ( Hủy)
( 8 , 4 , 11000000 , 1 ) , -- Đơn 4 mua Tom Ford
( 4 , 5 , 3800000 , 1 ) , -- Đơn 5 mua Ray- Ban Blue Light
( 6 , 6 , 9500000 , 1 ) , -- Đơn 6 mua Dior
( 11 , 7 , 2900000 , 1 ) , -- Đơn 7 mua Lacoste
( 12 , 8 , 1800000 , 3 ) , -- Đơn 8 mua 3 kính trẻ em ( 1.8tr x 3 = 5.4tr) ( Trả hàng)
( 6 , 9 , 9500000 , 1 ) , -- Đơn 9 mua Dior
( 5 , 9 , 5500000 , 1 ) ; -- Đơn 9 mua Oakley ( Mua 2 món cùng lúc)
-- 14 . B ảng Comments ( 9 Đánh giá)
INSERT INTO Comments ( product_id, order_id, rate, description) VALUES
( 3 , 1 , 5 , 'Kính rất xịn xò, đóng gói đẹp.' ) ,
( 6 , 6 , 4 , 'Chất lượng kính Dior rất tốt, nhưng giá hơi cao.' ) ,
( 12 , 8 , 2 , 'Kính hơi chật so với mặt bé, tôi muốn đổi trả.' ) ,
( 6 , 9 , 5 , 'Mua tặng vợ, vợ khen nức nở.' ) ,
( 5 , 9 , 5 , 'Oakley đạp xe bao ngầu, chống gió tốt.' ) ,
( 1 , 2 , 5 , 'Rayban kinh điển, không có gì để chê.' ) ,
( 4 , 5 , 4 , 'Đeo êm mắt khi dùng máy tính, gọng hơi nặng xíu.' ) ,
( 8 , 4 , 5 , 'Xứng đáng đồng tiền bát gạo.' ) ,
( 11 , 7 , 3 , 'Gọng nhựa trông hơi rẻ tiền so với hình ảnh.' ) ;
Q1JFQVRFIERBVEFCQVNFIElGIE5PVCBFWElTVFMgZ2xhc3Nlc19zaG9wX2RiIApDSEFSQUNURVIgU0VUIHV0ZjhtYjQgCkNPTExBVEUgdXRmOG1iNF91bmljb2RlX2NpOwoKVVNFIGdsYXNzZXNfc2hvcF9kYjsKCgoKCkRST1AgVEFCTEUgSUYgRVhJU1RTIFByb2R1Y3RfRGlzY291bnQ7CkRST1AgVEFCTEUgSUYgRVhJU1RTIENvbW1lbnRzOwpEUk9QIFRBQkxFIElGIEVYSVNUUyBQcm9kdWN0X09yZGVyOwpEUk9QIFRBQkxFIElGIEVYSVNUUyBPcmRlcnM7CkRST1AgVEFCTEUgSUYgRVhJU1RTIFVzZXJfQWRkcmVzczsKRFJPUCBUQUJMRSBJRiBFWElTVFMgVXNlcl9Sb2xlOwpEUk9QIFRBQkxFIElGIEVYSVNUUyBQcm9kdWN0czsKRFJPUCBUQUJMRSBJRiBFWElTVFMgVXNlcnM7CkRST1AgVEFCTEUgSUYgRVhJU1RTIFZvdWNoZXJzOwpEUk9QIFRBQkxFIElGIEVYSVNUUyBEaXNjb3VudHM7CkRST1AgVEFCTEUgSUYgRVhJU1RTIEFkZHJlc3M7CkRST1AgVEFCTEUgSUYgRVhJU1RTIENhdGVnb3JpZXM7CkRST1AgVEFCTEUgSUYgRVhJU1RTIEJyYW5kczsKRFJPUCBUQUJMRSBJRiBFWElTVFMgUm9sZXM7CgoKCgotLSAxLiBC4bqjbmcgVmFpIHRyw7IKQ1JFQVRFIFRBQkxFIFJvbGVzICgKICAgIHJvbGVfaWQgSU5UIFBSSU1BUlkgS0VZIEFVVE9fSU5DUkVNRU5ULAogICAgcm9sZV9uYW1lIFZBUkNIQVIoMjU1KSBOT1QgTlVMTCBVTklRVUUKKTsKCi0tIDIuIELhuqNuZyBUaMawxqFuZyBoaeG7h3UKQ1JFQVRFIFRBQkxFIEJyYW5kcyAoCiAgICBicmFuZF9pZCBJTlQgUFJJTUFSWSBLRVkgQVVUT19JTkNSRU1FTlQsCiAgICBicmFuZF9uYW1lIFZBUkNIQVIoMjU1KSBOT1QgTlVMTCwKICAgIGRlc2NyaXB0aW9uIFZBUkNIQVIoMjU1KQopOwoKLS0gMy4gQuG6o25nIERhbmggbeG7pWMgc+G6o24gcGjhuqltCkNSRUFURSBUQUJMRSBDYXRlZ29yaWVzICgKICAgIGNhdGVnb3J5X2lkIElOVCBQUklNQVJZIEtFWSBBVVRPX0lOQ1JFTUVOVCwKICAgIGNhdGVnb3J5X25hbWUgVkFSQ0hBUigyNTUpIE5PVCBOVUxMCik7CgotLSA0LiBC4bqjbmcgxJDhu4thIGNo4buJIChEw7luZyBjaHVuZykKQ1JFQVRFIFRBQkxFIEFkZHJlc3MgKAogICAgYWRkcmVzc19pZCBJTlQgUFJJTUFSWSBLRVkgQVVUT19JTkNSRU1FTlQsCiAgICBjaXR5IFZBUkNIQVIoMjU1KSBOT1QgTlVMTCwKICAgIHN0cmVldCBWQVJDSEFSKDI1NSkgTk9UIE5VTEwsCiAgICBzcGVjaWZpYWJsZV9hZGRyZXNzIFZBUkNIQVIoMjU1KQopOwoKLS0gNS4gQuG6o25nIEdp4bqjbSBnacOhCkNSRUFURSBUQUJMRSBEaXNjb3VudHMgKAogICAgZGlzY291bnRfaWQgSU5UIFBSSU1BUlkgS0VZIEFVVE9fSU5DUkVNRU5ULAogICAgZGlzY291bnRfcGVyY2VudCBJTlQgTk9UIE5VTEwsCiAgICBzdGFydF9kYXRlIERBVEUgTk9UIE5VTEwsCiAgICBlbmRfZGF0ZSBEQVRFIE5PVCBOVUxMLAogICAgaXNfYWN0aXZlIElOVCBERUZBVUxUIDEKKTsKCi0tIDYuIELhuqNuZyBWb3VjaGVyCkNSRUFURSBUQUJMRSBWb3VjaGVycyAoCiAgICB2b3VjaGVyX2lkIElOVCBQUklNQVJZIEtFWSBBVVRPX0lOQ1JFTUVOVCwKICAgIGRpc2NvdW50X3R5cGUgSU5UIE5PVCBOVUxMLCAtLSAxOiAlLCAyOiB0aeG7gW4gbeG6t3QKICAgIGRpc2NvdW50X3ZhbHVlIElOVCBOT1QgTlVMTCwKICAgIG1pbl9vcmRlcl92YWx1ZSBJTlQgTk9UIE5VTEwsCiAgICBtYXhfZGlzY291bnRfYW1vdW50IElOVCwKICAgIHVzYWdlX2xpbWl0IElOVCwKICAgIHVzZWRfY291bnQgSU5UIERFRkFVTFQgMCwKICAgIGV4cGlyeV9kYXRlIERBVEUgTk9UIE5VTEwKKTsKCgotLSA3LiBC4bqjbmcgTmfGsOG7nWkgZMO5bmcKQ1JFQVRFIFRBQkxFIFVzZXJzICgKICAgIHVzZXJfaWQgSU5UIFBSSU1BUlkgS0VZIEFVVE9fSU5DUkVNRU5ULAogICAgdXNlcl9uYW1lIFZBUkNIQVIoMjU1KSBOT1QgTlVMTCBVTklRVUUsCiAgICBwYXNzd29yZF9oYXNoIFZBUkNIQVIoMjU1KSBOT1QgTlVMTCwKICAgIGZ1bGxfbmFtZSBWQVJDSEFSKDI1NSkgTk9UIE5VTEwsCiAgICBlbWFpbCBWQVJDSEFSKDI1NSkgTk9UIE5VTEwgVU5JUVVFLAogICAgcGhvbmVfbnVtYmVyIFZBUkNIQVIoMjApCik7CgotLSA4LiBC4bqjbmcgU+G6o24gcGjhuqltCkNSRUFURSBUQUJMRSBQcm9kdWN0cyAoCiAgICBwcm9kdWN0X2lkIElOVCBQUklNQVJZIEtFWSBBVVRPX0lOQ1JFTUVOVCwKICAgIGNhdGVnb3J5X2lkIElOVCwKICAgIGJyYW5kX2lkIElOVCwKICAgIHByb2R1Y3RfbmFtZSBWQVJDSEFSKDI1NSkgTk9UIE5VTEwsCiAgICBtYXRlcmlhbCBWQVJDSEFSKDI1NSksCiAgICBzaGFwZSBWQVJDSEFSKDI1NSksCiAgICBiYXNlX3ByaWNlIElOVCBOT1QgTlVMTCwKICAgIHN0b2NrX3F1YW50aXR5IElOVCBERUZBVUxUIDAsCiAgICBkZXNjcmlwdGlvbiBURVhULAogICAgRk9SRUlHTiBLRVkgKGNhdGVnb3J5X2lkKSBSRUZFUkVOQ0VTIENhdGVnb3JpZXMoY2F0ZWdvcnlfaWQpLAogICAgRk9SRUlHTiBLRVkgKGJyYW5kX2lkKSBSRUZFUkVOQ0VTIEJyYW5kcyhicmFuZF9pZCkKKTsKCgoKLS0gOS4gTGnDqm4ga+G6v3QgVXNlciAtIFJvbGUgKE4tTikKQ1JFQVRFIFRBQkxFIFVzZXJfUm9sZSAoCiAgICB1c2VyX2lkIElOVCwKICAgIHJvbGVfaWQgSU5ULAogICAgUFJJTUFSWSBLRVkgKHVzZXJfaWQsIHJvbGVfaWQpLAogICAgRk9SRUlHTiBLRVkgKHVzZXJfaWQpIFJFRkVSRU5DRVMgVXNlcnModXNlcl9pZCkgT04gREVMRVRFIENBU0NBREUsCiAgICBGT1JFSUdOIEtFWSAocm9sZV9pZCkgUkVGRVJFTkNFUyBSb2xlcyhyb2xlX2lkKSBPTiBERUxFVEUgQ0FTQ0FERQopOwoKLS0gMTAuIExpw6puIGvhur90IFVzZXIgLSBBZGRyZXNzIChOLU4pCkNSRUFURSBUQUJMRSBVc2VyX0FkZHJlc3MgKAogICAgdXNlcl9pZCBJTlQsCiAgICBhZGRyZXNzX2lkIElOVCwKICAgIFBSSU1BUlkgS0VZICh1c2VyX2lkLCBhZGRyZXNzX2lkKSwKICAgIEZPUkVJR04gS0VZICh1c2VyX2lkKSBSRUZFUkVOQ0VTIFVzZXJzKHVzZXJfaWQpIE9OIERFTEVURSBDQVNDQURFLAogICAgRk9SRUlHTiBLRVkgKGFkZHJlc3NfaWQpIFJFRkVSRU5DRVMgQWRkcmVzcyhhZGRyZXNzX2lkKSBPTiBERUxFVEUgQ0FTQ0FERQopOwoKLS0gMTEuIMSQxqFuIGjDoG5nCkNSRUFURSBUQUJMRSBPcmRlcnMgKAogICAgb3JkZXJfaWQgSU5UIFBSSU1BUlkgS0VZIEFVVE9fSU5DUkVNRU5ULAogICAgdXNlcl9pZCBJTlQsCiAgICBhZGRyZXNzX2lkIElOVCwKICAgIHZvdWNoZXJfaWQgSU5ULAogICAgdG90YWxfcHJpY2UgSU5UIE5PVCBOVUxMLAogICAgZGlzY291bnRfYW1vdW50IElOVCBERUZBVUxUIDAsCiAgICBzdGF0dXMgVkFSQ0hBUigyMCkgREVGQVVMVCAnUGVuZGluZycsCiAgICBvcmRlcl9kYXRlIERBVEVUSU1FIERFRkFVTFQgQ1VSUkVOVF9USU1FU1RBTVAsCiAgICBGT1JFSUdOIEtFWSAodXNlcl9pZCkgUkVGRVJFTkNFUyBVc2Vycyh1c2VyX2lkKSwKICAgIEZPUkVJR04gS0VZIChhZGRyZXNzX2lkKSBSRUZFUkVOQ0VTIEFkZHJlc3MoYWRkcmVzc19pZCksCiAgICBGT1JFSUdOIEtFWSAodm91Y2hlcl9pZCkgUkVGRVJFTkNFUyBWb3VjaGVycyh2b3VjaGVyX2lkKQopOwoKLS0gMTIuIENoaSB0aeG6v3QgxJHGoW4gaMOgbmcgKE4tTiBnaeG7r2EgUHJvZHVjdCB2w6AgT3JkZXIpCkNSRUFURSBUQUJMRSBQcm9kdWN0X09yZGVyICgKICAgIHByb2R1Y3RfaWQgSU5ULAogICAgb3JkZXJfaWQgSU5ULAogICAgcHJpY2VfYXRfcHVyY2hhc2UgSU5UIE5PVCBOVUxMLAogICAgcXVhbnRpdHkgSU5UIE5PVCBOVUxMLAogICAgUFJJTUFSWSBLRVkgKHByb2R1Y3RfaWQsIG9yZGVyX2lkKSwKICAgIEZPUkVJR04gS0VZIChwcm9kdWN0X2lkKSBSRUZFUkVOQ0VTIFByb2R1Y3RzKHByb2R1Y3RfaWQpLAogICAgRk9SRUlHTiBLRVkgKG9yZGVyX2lkKSBSRUZFUkVOQ0VTIE9yZGVycyhvcmRlcl9pZCkgT04gREVMRVRFIENBU0NBREUKKTsKCi0tIDEzLiBDb21tZW50ICYgxJDDoW5oIGdpw6EKQ1JFQVRFIFRBQkxFIENvbW1lbnRzICgKICAgIGNvbW1lbnRfaWQgSU5UIFBSSU1BUlkgS0VZIEFVVE9fSU5DUkVNRU5ULAogICAgcHJvZHVjdF9pZCBJTlQsCiAgICBvcmRlcl9pZCBJTlQsCiAgICByYXRlIElOVCBDSEVDSyAocmF0ZSBCRVRXRUVOIDEgQU5EIDUpLAogICAgZGVzY3JpcHRpb24gVEVYVCwKICAgIEZPUkVJR04gS0VZIChwcm9kdWN0X2lkKSBSRUZFUkVOQ0VTIFByb2R1Y3RzKHByb2R1Y3RfaWQpLAogICAgRk9SRUlHTiBLRVkgKG9yZGVyX2lkKSBSRUZFUkVOQ0VTIE9yZGVycyhvcmRlcl9pZCkKKTsKCi0tIDE0LiBMacOqbiBr4bq/dCBQcm9kdWN0IC0gRGlzY291bnQgKE4tTikKQ1JFQVRFIFRBQkxFIFByb2R1Y3RfRGlzY291bnQgKAogICAgcHJvZHVjdF9pZCBJTlQsCiAgICBkaXNjb3VudF9pZCBJTlQsCiAgICBQUklNQVJZIEtFWSAocHJvZHVjdF9pZCwgZGlzY291bnRfaWQpLAogICAgRk9SRUlHTiBLRVkgKHByb2R1Y3RfaWQpIFJFRkVSRU5DRVMgUHJvZHVjdHMocHJvZHVjdF9pZCksCiAgICBGT1JFSUdOIEtFWSAoZGlzY291bnRfaWQpIFJFRkVSRU5DRVMgRGlzY291bnRzKGRpc2NvdW50X2lkKQopOwoKCgotLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0gUEjhuqZOIDM6IElOU0VSVCBE4buuIExJ4buGVSBN4bqqVSAoU0VFRCBEQVRBIC0gQuG6ok4gWDMgROG7riBMSeG7hlUpCi0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLS0gMS4gQuG6o25nIFJvbGVzICg5IFZhaSB0csOyKQpJTlNFUlQgSU5UTyBSb2xlcyAocm9sZV9uYW1lKSBWQUxVRVMgCignQURNSU4nKSwgCignQ1VTVE9NRVInKSwgCignU1RBRkYnKSwKKCdNQU5BR0VSJyksCignTUFSS0VUSU5HJyksCignQUNDT1VOVEFOVCcpLAooJ1dBUkVIT1VTRScpLAooJ1NVUFBPUlQnKSwKKCdHVUVTVCcpOwoKLS0gMi4gQuG6o25nIEJyYW5kcyAoMTIgVGjGsMahbmcgaGnhu4d1KQpJTlNFUlQgSU5UTyBCcmFuZHMgKGJyYW5kX25hbWUsIGRlc2NyaXB0aW9uKSBWQUxVRVMgCignUmF5LUJhbicsICdUaMawxqFuZyBoaeG7h3UgbeG6r3Qga8OtbmggaHV54buBbiB0aG/huqFpIHThu6sgTeG7uScpLAooJ0d1Y2NpJywgJ0vDrW5oIG3huq90IHRo4budaSB0cmFuZyBjYW8gY+G6pXAgdOG7qyDDnScpLAooJ0dlbnRsZSBNb25zdGVyJywgJ1RoxrDGoW5nIGhp4buHdSB0aOG7nWkgdHJhbmcgZ2nhu5tpIHRy4bq7IEjDoG4gUXXhu5FjJyksCignT2FrbGV5JywgJ0vDrW5oIHRo4buDIHRoYW8gY2h1ecOqbiBk4bulbmcnKSwKKCdEaW9yJywgJ1Ro4budaSB0cmFuZyB4YSB44buJIHThu6sgUGjDoXAnKSwKKCdQcmFkYScsICdQaG9uZyBjw6FjaCB0aGFuaCBs4buLY2ggdsOgIGhp4buHbiDEkeG6oWknKSwKKCdUb20gRm9yZCcsICdTYW5nIHRy4buNbmcsIMSR4bqzbmcgY+G6pXAgZMOgbmggY2hvIGRvYW5oIG5ow6JuJyksCignQ2FycmVyYScsICdUaGnhur90IGvhur8gbmFtIHTDrW5oLCBt4bqhbmggbeG6vScpLAooJ1BvbGljZScsICdQaG9uZyBjw6FjaCDEkcaw4budbmcgcGjhu5Egw50nKSwKKCdMYWNvc3RlJywgJ1RoYW5oIGzhu4tjaCBwaGEgbOG6q24gdGjhu4MgdGhhbycpLAooJ0NhbHZpbiBLbGVpbicsICdU4buRaSBnaeG6o24sIHRy4bq7IHRydW5nJyksCignV2FyYnkgUGFya2VyJywgJ1RoxrDGoW5nIGhp4buHdSBrw61uaCBnacOhIHThu5F0IGNo4bqldCBsxrDhu6NuZyBjYW8nKTsKCi0tIDMuIELhuqNuZyBDYXRlZ29yaWVzICgxMiBEYW5oIG3hu6VjKQpJTlNFUlQgSU5UTyBDYXRlZ29yaWVzIChjYXRlZ29yeV9uYW1lKSBWQUxVRVMgCignS8OtbmggcsOibSAoU3VuZ2xhc3NlcyknKSwKKCdLw61uaCBj4bqtbiAoUHJlc2NyaXB0aW9uIEdsYXNzZXMpJyksCignS8OtbmggY2jhu5FuZyDDoW5oIHPDoW5nIHhhbmgnKSwKKCdLw61uaCB0aOG7gyB0aGFvJyksCignS8Otbmggdmnhu4VuJyksCignS8OtbmggbMOjbycpLAooJ0vDrW5oIHRo4budaSB0cmFuZyBraMO0bmcgxJHhu5knKSwKKCdLw61uaCBixqFpJyksCignS8OtbmggYuG6o28gaOG7mScpLAooJ0vDrW5oIHBow6JuIGPhu7FjIChQb2xhcml6ZWQpJyksCignS8OtbmggdHLhursgZW0nKSwKKCdH4buNbmcga8OtbmggVGl0YW5pdW0nKTsKCi0tIDQuIELhuqNuZyBBZGRyZXNzICgxMiDEkOG7i2EgY2jhu4kpCklOU0VSVCBJTlRPIEFkZHJlc3MgKGNpdHksIHN0cmVldCwgc3BlY2lmaWFibGVfYWRkcmVzcykgVkFMVUVTIAooJ0jDoCBO4buZaScsICdD4bqndSBHaeG6pXknLCAnU+G7kSAxMCwgbmfDtSAyMCcpLAooJ0jDoCBO4buZaScsICdIw6AgxJDDtG5nJywgJ0vDvSB0w7pjIHjDoSBQVElUJyksCignVFAuIEjhu5MgQ2jDrSBNaW5oJywgJ1F14bqtbiAxJywgJ1TDsmEgbmjDoCBCaXRleGNvLCBz4buRIDIgSOG6o2kgVHJp4buBdScpLAooJ8SQw6AgTuG6tW5nJywgJ0jhuqNpIENow6J1JywgJzE1IEzDqiBEdeG6qW4nKSwKKCdIw6AgTuG7mWknLCAnxJDhu5FuZyDEkGEnLCAnU+G7kSA1LCBuZ8O1IFRow6FpIEjDoCcpLAooJ1RQLiBI4buTIENow60gTWluaCcsICdRdeG6rW4gNycsICdLaHUgxJHDtCB0aOG7iyBQaMO6IE3hu7kgSMawbmcnKSwKKCdI4bqjaSBQaMOybmcnLCAnTMOqIENow6JuJywgJzEyMCBUw7QgSGnhu4d1JyksCignQ+G6p24gVGjGoScsICdOaW5oIEtp4buBdScsICczNiBN4bqtdSBUaMOibicpLAooJ8SQw6AgTOG6oXQnLCAnUGjGsOG7nW5nIDEnLCAnS2h1IEjDsmEgQsOsbmgnKSwKKCdOaGEgVHJhbmcnLCAnTOG7mWMgVGjhu40nLCAnNzggVHLhuqduIFBow7onKSwKKCdIdeG6vycsICdQaMO6IE5odeG6rW4nLCAnMTIgTMOqIEzhu6NpJyksCignxJDDoCBO4bq1bmcnLCAnU8ahbiBUcsOgJywgJ8SQxrDhu51uZyBQaOG6oW0gVsSDbiDEkOG7k25nJyk7CgotLSA1LiBC4bqjbmcgRGlzY291bnRzICg5IEdp4bqjbSBnacOhKQpJTlNFUlQgSU5UTyBEaXNjb3VudHMgKGRpc2NvdW50X3BlcmNlbnQsIHN0YXJ0X2RhdGUsIGVuZF9kYXRlLCBpc19hY3RpdmUpIFZBTFVFUyAKKDEwLCAnMjAyNi0wMS0wMScsICcyMDI2LTEyLTMxJywgMSksIC0tIMSQYW5nIGhv4bqhdCDEkeG7mW5nCig1MCwgJzIwMjUtMDEtMDEnLCAnMjAyNS0wMS0zMScsIDApLCAtLSDEkMOjIGjhur90IGjhuqFuCigyMCwgJzIwMjYtMDQtMDEnLCAnMjAyNi0wNC0zMCcsIDEpLCAtLSDEkGFuZyBob+G6oXQgxJHhu5luZyB0aMOhbmcgbsOgeQooMTUsICcyMDI2LTA1LTAxJywgJzIwMjYtMDUtMzEnLCAxKSwgLS0gU+G6r3AgZGnhu4VuIHJhCig1LCAnMjAyNi0wMS0wMScsICcyMDI2LTEyLTMxJywgMSksICAtLSBHaeG6o20gbmjhurkKKDcwLCAnMjAyNS0xMS0yMCcsICcyMDI1LTExLTI1JywgMCksIC0tIMSQw6MgaOG6v3QgaOG6oW4gKEJsYWNrIEZyaWRheSBjxakpCigyNSwgJzIwMjYtMDMtMDEnLCAnMjAyNi0wMy0zMScsIDApLCAtLSBW4burYSBo4bq/dCBo4bqhbgooMzAsICcyMDI2LTA2LTAxJywgJzIwMjYtMDgtMzEnLCAxKSwgLS0gR2nhuqNtIGdpw6EgbcO5YSBow6gKKDEyLCAnMjAyNi0wNC0xNScsICcyMDI2LTA0LTIwJywgMSk7IC0tIEdp4bqjbSBnacOhIGNo4bubcCBuaG/DoW5nIChGbGFzaCBzYWxlKQoKLS0gNi4gQuG6o25nIFZvdWNoZXJzICg5IFZvdWNoZXIgxJFhIGThuqFuZykKSU5TRVJUIElOVE8gVm91Y2hlcnMgKGRpc2NvdW50X3R5cGUsIGRpc2NvdW50X3ZhbHVlLCBtaW5fb3JkZXJfdmFsdWUsIG1heF9kaXNjb3VudF9hbW91bnQsIHVzYWdlX2xpbWl0LCB1c2VkX2NvdW50LCBleHBpcnlfZGF0ZSkgVkFMVUVTIAooMSwgMTUsIDEwMDAwMDAsIDUwMDAwMCwgMTAwLCAxMCwgJzIwMjYtMTItMzEnKSwgLS0gR2nhuqNtIDE1JQooMiwgMTAwMDAwLCA1MDAwMDAsIDEwMDAwMCwgNTAsIDUsICcyMDI2LTEyLTMxJyksICAtLSBHaeG6o20gMTAwawooMSwgMTAsIDAsIE5VTEwsIDUwMCwgNTAwLCAnMjAyNi0xMi0zMScpLCAgICAgICAgLS0gTOG7l2kgaOG6v3QgbMaw4bujdCBkw7luZwooMiwgNTAwMDAsIDIwMDAwMCwgNTAwMDAsIDEwMDAsIDEyMCwgJzIwMjYtMDYtMzAnKSwtLSBWb3VjaGVyIGZyZWVzaGlwIGdp4bqjIGzhuq1wCigxLCAyMCwgMjAwMDAwMCwgODAwMDAwLCAyMCwgMCwgJzIwMjYtMDUtMTUnKSwgICAgIC0tIFZvdWNoZXIgZ2nDoSB0cuG7iyBjYW8sIMOtdCBsxrDhu6N0CigyLCAyMDAwMDAsIDE1MDAwMDAsIDIwMDAwMCwgMTAwLCA5OSwgJzIwMjYtMTItMzEnKSwtLSBT4bqvcCBo4bq/dCBsxrDhu6N0CigxLCA1LCAwLCA1MDAwMCwgMTAwMDAsIDQ1MCwgJzIwMjctMDEtMDEnKSwgICAgICAgIC0tIFZvdWNoZXIgcGjhu5UgdGjDtG5nCigyLCA1MDAwMDAsIDUwMDAwMDAsIDUwMDAwMCwgMTAsIDEwLCAnMjAyNi0wNC0zMCcpLC0tIMSQw6MgaOG6v3QgbMaw4bujdAooMSwgNTAsIDAsIDEwMDAwMCwgNTAsIDAsICcyMDI1LTEyLTMxJyk7ICAgICAgICAgICAtLSDEkMOjIGjhur90IGjhuqFuIHPhu60gZOG7pW5nCgotLSA3LiBC4bqjbmcgVXNlcnMgKDkgTmfGsOG7nWkgZMO5bmcpCklOU0VSVCBJTlRPIFVzZXJzICh1c2VyX25hbWUsIHBhc3N3b3JkX2hhc2gsIGZ1bGxfbmFtZSwgZW1haWwsIHBob25lX251bWJlcikgVkFMVUVTIAooJ2FkbWluX3Jvb3QnLCAnJDJhJDEyJERVTU1ZSEFTSEZPUjEyMzQ1NicsICdRdeG6o24gVHLhu4sgVmnDqm4nLCAnYWRtaW5AZ2xhc3Nlc3Nob3Audm4nLCAnMDkwMDAwMDAwMCcpLAooJ2Rldl90ZXN0ZXInLCAnJDJhJDEyJERVTU1ZSEFTSEZPUjEyMzQ1NicsICdL4bu5IFPGsCBI4buHIFRo4buRbmcnLCAnZGV2QGdtYWlsLmNvbScsICcwOTEyMzQ1Njc4JyksCignbWFpX25ndXllbicsICckMmEkMTIkRFVNTVlIQVNIRk9SMTIzNDU2JywgJ05ndXnhu4VuIFRo4buLIE1haScsICdtYWkubmd1eWVuQHlhaG9vLmNvbScsICcwOTg3NjU0MzIxJyksCignaG9hbmdfbmFtJywgJyQyYSQxMiREVU1NWUhBU0hGT1IxMjM0NTYnLCAnVHLhuqduIEhvw6BuZyBOYW0nLCAnbmFtLnRyYW5AZ21haWwuY29tJywgJzA5MzMxMTIyMzMnKSwKKCdsaW5oX2NoaScsICckMmEkMTIkRFVNTVlIQVNIRk9SMTIzNDU2JywgJ0zDqiBMaW5oIENoaScsICdjaGkubGVAaG90bWFpbC5jb20nLCAnMDkxMTIyMzM0NCcpLAooJ3R1YW5fYW5oJywgJyQyYSQxMiREVU1NWUhBU0hGT1IxMjM0NTYnLCAnUGjhuqFtIFR14bqlbiBBbmgnLCAndHVhbmFuaC5waGFtQGdsYXNzZXNzaG9wLnZuJywgJzA5NDQ1NTY2NzcnKSwKKCdxdXluaF9uaHUnLCAnJDJhJDEyJERVTU1ZSEFTSEZPUjEyMzQ1NicsICdWxakgUXXhu7NuaCBOaMawJywgJ25odS52dUBnbWFpbC5jb20nLCAnMDk2Njc3ODg5OScpLAooJ3F1YW5nX2hhaScsICckMmEkMTIkRFVNTVlIQVNIRk9SMTIzNDU2JywgJ05ndXnhu4VuIFF1YW5nIEjhuqNpJywgJ2hhaS5uZ3V5ZW5AeWFob28uY29tJywgJzA5Nzc4ODk5MDAnKSwKKCdiYW9fdHJhbScsICckMmEkMTIkRFVNTVlIQVNIRk9SMTIzNDU2JywgJ8SQ4buXIELhuqNvIFRyw6JtJywgJ3RyYW0uZG9AZ21haWwuY29tJywgJzA5ODg5OTAwMTEnKTsKCi0tIDguIELhuqNuZyBQcm9kdWN0cyAoMTUgU+G6o24gcGjhuqltIMSRYSBk4bqhbmcpCklOU0VSVCBJTlRPIFByb2R1Y3RzIChjYXRlZ29yeV9pZCwgYnJhbmRfaWQsIHByb2R1Y3RfbmFtZSwgbWF0ZXJpYWwsIHNoYXBlLCBiYXNlX3ByaWNlLCBzdG9ja19xdWFudGl0eSwgZGVzY3JpcHRpb24pIFZBTFVFUyAKKDEsIDEsICdSYXktQmFuIEF2aWF0b3IgQ2xhc3NpYycsICdLaW0gbG/huqFpJywgJ0F2aWF0b3InLCA0NTAwMDAwLCAyMCwgJ0vDrW5oIHLDom0gcGhpIGPDtG5nIG3DoHUgeGFuaCBs4bulYyBj4buVIMSRaeG7g24nKSwKKDIsIDIsICdHdWNjaSBTcXVhcmUgT3B0aWNhbCcsICdOaOG7sWEgQWNldGF0ZScsICdWdcO0bmcnLCA4MjAwMDAwLCA1LCAnR+G7jW5nIGvDrW5oIGPhuq1uIHRo4budaSB0cmFuZyBuYW0gbuG7ryBjYW8gY+G6pXAnKSwKKDEsIDMsICdHZW50bGUgTW9uc3RlciBMaWxpdCcsICdOaOG7sWEgQWNldGF0ZScsICdWdcO0bmcgYm8gZ8OzYycsIDY1MDAwMDAsIDAsICdLw61uaCByw6JtIGhvdCB0cmVuZCAoSOG6v3QgaMOgbmcpJyksCigzLCAxLCAnUmF5LUJhbiBDbHVibWFzdGVyIEJsdWUtTGlnaHQnLCAnSOG7l24gaOG7o3AnLCAnQ2x1Ym1hc3RlcicsIDM4MDAwMDAsIDMwLCAnTeG6r3Qga8OtbmggYuG6o28gduG7hyBt4bqvdCcpLAooNCwgNCwgJ09ha2xleSBSYWRhciBFViBQYXRoJywgJ05o4buxYSBPIE1hdHRlcicsICdUaOG7gyB0aGFvJywgNTUwMDAwMCwgMTAsICdLw61uaCDEkeG6oXAgeGUgY2h1ecOqbiBuZ2hp4buHcCcpLAooMSwgNSwgJ0Rpb3JTdGVsbGFpcmUxJywgJ0tpbSBsb+G6oWknLCAnVnXDtG5nIGzhu5tuJywgOTUwMDAwMCwgMywgJ0vDrW5oIHLDom0gbuG7ryB0aGnhur90IGvhur8gb3ZlcnNpemUgc2FuZyB0cuG7jW5nJyksCigyLCA2LCAnUHJhZGEgTWluaW1hbCBCYXJvcXVlJywgJ05o4buxYScsICdUcsOybicsIDc4MDAwMDAsIDEyLCAnR+G7jW5nIGvDrW5oIGPhuq1uIGjhu41hIHRp4bq/dCB4b+G6r24g4buRYyDEkeG7mWMgxJHDoW8nKSwKKDUsIDcsICdUb20gRm9yZCBGVDU0MDEnLCAnS2ltIGxv4bqhaScsICdDaOG7ryBuaOG6rXQnLCAxMTAwMDAwMCwgOCwgJ0vDrW5oIHZp4buFbiBjYW8gY+G6pXAgY2hvIG5hbSBnaeG7m2knKSwKKDYsIDgsICdDYXJyZXJhIDEwMDUvUycsICdI4buXbiBo4bujcCcsICdQaGkgY8O0bmcnLCA0MjAwMDAwLCAyNSwgJ0vDrW5oIHLDom0gbmFtIHTDrW5oIG3huqFuaCBt4bq9JyksCigxMCwgOSwgJ1BvbGljZSBPcmlnaW5zIDEnLCAnSOG7o3Aga2ltJywgJ1Z1w7RuZycsIDM2MDAwMDAsIDE1LCAnS8OtbmggcGjDom4gY+G7sWMgY2jhu5FuZyBsw7NhIGtoaSBsw6FpIHhlJyksCig3LCAxMCwgJ0xhY29zdGUgTDI3NjcnLCAnTmjhu7FhIGThurtvJywgJ0No4buvIG5o4bqtdCcsIDI5MDAwMDAsIDUwLCAnS8OtbmggdGjhu51pIHRyYW5nIGtow7RuZyDEkeG7mSBmb3JtIGfhu41uIG5o4bq5JyksCigxMSwgMSwgJ1JheS1CYW4gSnVuaW9yIFJKOTA1MlMnLCAnTmjhu7FhIGFuIHRvw6BuJywgJ1Ryw7JuJywgMTgwMDAwMCwgNDAsICdLw61uaCByw6JtIGLhuqNvIHbhu4cgbeG6r3QgY2hvIHRy4bq7IGVtJyksCigxMiwgMTEsICdDSyBUaXRhbml1bSBSaW1sZXNzJywgJ1RpdGFuaXVtJywgJ0tow7RuZyB2aeG7gW4nLCA1MjAwMDAwLCAxOCwgJ0fhu41uZyBrw61uaCBzacOqdSBuaOG6uSB0w6BuZyBow6xuaCB0csOqbiBt4bq3dCcpLAooOCwgNCwgJ09ha2xleSBTd2ltIEdvZ2dsZXMnLCAnU2lsaWNvbmUnLCAnVGjhu4MgdGhhbycsIDEyMDAwMDAsIDYwLCAnS8OtbmggYsahaSBjaOG7kW5nIHPGsMahbmcgbcO5JyksCigyLCAxMiwgJ1dhcmJ5IFBhcmtlciBIYXNrZWxsJywgJ05o4buxYSB0w6FpIGNo4bq/JywgJ1Ryw7JuJywgMjUwMDAwMCwgMCwgJ0fhu41uZyBrw61uaCB0aMOibiB0aGnhu4duIG3DtGkgdHLGsOG7nW5nICjEkGFuZyDEkeG7o2kgaMOgbmcgduG7gSknKTsKCi0tIDkuIELhuqNuZyBVc2VyX1JvbGUgKDkgTGnDqm4ga+G6v3QpCklOU0VSVCBJTlRPIFVzZXJfUm9sZSAodXNlcl9pZCwgcm9sZV9pZCkgVkFMVUVTIAooMSwgMSksIC0tIGFkbWluX3Jvb3QgbMOgIEFETUlOCigyLCAyKSwgLS0gZGV2X3Rlc3RlciBsw6AgQ1VTVE9NRVIKKDMsIDIpLCAtLSBtYWlfbmd1eWVuIGzDoCBDVVNUT01FUgooNCwgMiksIC0tIGhvYW5nX25hbSBsw6AgQ1VTVE9NRVIKKDUsIDIpLCAtLSBsaW5oX2NoaSBsw6AgQ1VTVE9NRVIKKDYsIDMpLCAtLSB0dWFuX2FuaCBsw6AgU1RBRkYKKDcsIDQpLCAtLSBxdXluaF9uaHUgbMOgIE1BTkFHRVIKKDgsIDIpLCAtLSBxdWFuZ19oYWkgbMOgIENVU1RPTUVSCig5LCAyKTsgLS0gYmFvX3RyYW0gbMOgIENVU1RPTUVSCgotLSAxMC4gQuG6o25nIFVzZXJfQWRkcmVzcyAoOSBMacOqbiBr4bq/dCkKSU5TRVJUIElOVE8gVXNlcl9BZGRyZXNzICh1c2VyX2lkLCBhZGRyZXNzX2lkKSBWQUxVRVMgCigxLCAxKSwKKDIsIDIpLCAKKDMsIDMpLAooNCwgNCksCig1LCA1KSwKKDYsIDYpLAooNywgNyksCig4LCA4KSwKKDksIDkpOwoKLS0gMTEuIELhuqNuZyBQcm9kdWN0X0Rpc2NvdW50ICg2IExpw6puIGvhur90KQpJTlNFUlQgSU5UTyBQcm9kdWN0X0Rpc2NvdW50IChwcm9kdWN0X2lkLCBkaXNjb3VudF9pZCkgVkFMVUVTIAooMywgMyksICAtLSBHZW50bGUgTW9uc3RlciDEkcaw4bujYyBnaeG6o20gMjAlCig0LCAxKSwgIC0tIFJheS1CYW4gQmx1ZS1saWdodCBnaeG6o20gMTAlCig4LCA1KSwgIC0tIFRvbSBGb3JkIGdp4bqjbSA1JQooMTIsIDgpLCAtLSBLw61uaCB0cuG6uyBlbSBnaeG6o20gMzAlIGjDqAooMSwgMiksICAtLSBI4bq/dCBo4bqhbiBnaeG6o20gZ2nDoQooMTUsIDEpOyAtLSBXYXJieSBQYXJrZXIgZ2nhuqNtIDEwJQoKLS0gMTIuIELhuqNuZyBPcmRlcnMgKDkgxJDGoW4gaMOgbmcgxJFhIGThuqFuZyB0cuG6oW5nIHRow6FpKQpJTlNFUlQgSU5UTyBPcmRlcnMgKHVzZXJfaWQsIGFkZHJlc3NfaWQsIHZvdWNoZXJfaWQsIHRvdGFsX3ByaWNlLCBkaXNjb3VudF9hbW91bnQsIHN0YXR1cywgb3JkZXJfZGF0ZSkgVkFMVUVTIAooMiwgMiwgMSwgNjUwMDAwMCwgNTAwMDAwLCAnQ29tcGxldGVkJywgJzIwMjYtMDQtMTAgMTA6MDA6MDAnKSwKKDMsIDMsIE5VTEwsIDQ1MDAwMDAsIDAsICdQZW5kaW5nJywgJzIwMjYtMDQtMTQgMTU6MzA6MDAnKSwgICAKKDIsIDIsIE5VTEwsIDgyMDAwMDAsIDAsICdDYW5jZWxsZWQnLCAnMjAyNi0wNC0xMiAwODowMDowMCcpLAooNCwgNCwgMiwgMTEwMDAwMDAsIDEwMDAwMCwgJ1Byb2Nlc3NpbmcnLCAnMjAyNi0wNC0xNSAwOTowMDowMCcpLAooNSwgNSwgNCwgMzgwMDAwMCwgNTAwMDAsICdTaGlwcGluZycsICcyMDI2LTA0LTEzIDE0OjIwOjAwJyksCig4LCA4LCBOVUxMLCA5NTAwMDAwLCAwLCAnQ29tcGxldGVkJywgJzIwMjYtMDMtMjAgMTE6MTU6MDAnKSwKKDksIDksIDcsIDI5MDAwMDAsIDUwMDAwLCAnUGVuZGluZycsICcyMDI2LTA0LTE1IDEwOjMwOjAwJyksCigzLCAzLCBOVUxMLCA1NDAwMDAwLCAwLCAnUmV0dXJuZWQnLCAnMjAyNi0wMi0xNCAxNjo0NTowMCcpLAooNCwgNCwgNSwgMTUwMDAwMDAsIDgwMDAwMCwgJ0NvbXBsZXRlZCcsICcyMDI2LTAxLTA1IDA4OjMwOjAwJyk7CgotLSAxMy4gQuG6o25nIFByb2R1Y3RfT3JkZXIgKDE0IENoaSB0aeG6v3Qgc+G6o24gcGjhuqltIHRyb25nIMSRxqFuKQpJTlNFUlQgSU5UTyBQcm9kdWN0X09yZGVyIChwcm9kdWN0X2lkLCBvcmRlcl9pZCwgcHJpY2VfYXRfcHVyY2hhc2UsIHF1YW50aXR5KSBWQUxVRVMgCigzLCAxLCA2NTAwMDAwLCAxKSwgIC0tIMSQxqFuIDEgbXVhIEdlbnRsZSBNb25zdGVyCigxLCAyLCA0NTAwMDAwLCAxKSwgIC0tIMSQxqFuIDIgbXVhIFJheS1CYW4KKDIsIDMsIDgyMDAwMDAsIDEpLCAgLS0gxJDGoW4gMyBtdWEgR3VjY2kgKEjhu6d5KQooOCwgNCwgMTEwMDAwMDAsIDEpLCAtLSDEkMahbiA0IG11YSBUb20gRm9yZAooNCwgNSwgMzgwMDAwMCwgMSksICAtLSDEkMahbiA1IG11YSBSYXktQmFuIEJsdWUgTGlnaHQKKDYsIDYsIDk1MDAwMDAsIDEpLCAgLS0gxJDGoW4gNiBtdWEgRGlvcgooMTEsIDcsIDI5MDAwMDAsIDEpLCAtLSDEkMahbiA3IG11YSBMYWNvc3RlCigxMiwgOCwgMTgwMDAwMCwgMyksIC0tIMSQxqFuIDggbXVhIDMga8OtbmggdHLhursgZW0gKDEuOHRyIHggMyA9IDUuNHRyKSAoVHLhuqMgaMOgbmcpCig2LCA5LCA5NTAwMDAwLCAxKSwgIC0tIMSQxqFuIDkgbXVhIERpb3IKKDUsIDksIDU1MDAwMDAsIDEpOyAgLS0gxJDGoW4gOSBtdWEgT2FrbGV5IChNdWEgMiBtw7NuIGPDuW5nIGzDumMpCgotLSAxNC4gQuG6o25nIENvbW1lbnRzICg5IMSQw6FuaCBnacOhKQpJTlNFUlQgSU5UTyBDb21tZW50cyAocHJvZHVjdF9pZCwgb3JkZXJfaWQsIHJhdGUsIGRlc2NyaXB0aW9uKSBWQUxVRVMgCigzLCAxLCA1LCAnS8OtbmggcuG6pXQgeOG7i24geMOyLCDEkcOzbmcgZ8OzaSDEkeG6uXAuJyksCig2LCA2LCA0LCAnQ2jhuqV0IGzGsOG7o25nIGvDrW5oIERpb3IgcuG6pXQgdOG7kXQsIG5oxrBuZyBnacOhIGjGoWkgY2FvLicpLAooMTIsIDgsIDIsICdLw61uaCBoxqFpIGNo4bqtdCBzbyB24bubaSBt4bq3dCBiw6ksIHTDtGkgbXXhu5FuIMSR4buVaSB0cuG6oy4nKSwKKDYsIDksIDUsICdNdWEgdOG6t25nIHbhu6MsIHbhu6Mga2hlbiBu4bupYyBu4bufLicpLAooNSwgOSwgNSwgJ09ha2xleSDEkeG6oXAgeGUgYmFvIG5n4bqndSwgY2jhu5FuZyBnacOzIHThu5F0LicpLAooMSwgMiwgNSwgJ1JheWJhbiBraW5oIMSRaeG7g24sIGtow7RuZyBjw7MgZ8OsIMSR4buDIGNow6ouJyksCig0LCA1LCA0LCAnxJBlbyDDqm0gbeG6r3Qga2hpIGTDuW5nIG3DoXkgdMOtbmgsIGfhu41uZyBoxqFpIG7hurduZyB4w611LicpLAooOCwgNCwgNSwgJ1jhu6luZyDEkcOhbmcgxJHhu5NuZyB0aeG7gW4gYsOhdCBn4bqhby4nKSwKKDExLCA3LCAzLCAnR+G7jW5nIG5o4buxYSB0csO0bmcgaMahaSBy4bq7IHRp4buBbiBzbyB24bubaSBow6xuaCDhuqNuaC4nKTs=