├── Screenshot.png ├── img └── loading.gif ├── css ├── styles.css └── fancybox.css ├── js ├── client │ ├── apiGatewayClient.js │ ├── utils.js │ ├── simpleHttpClient.js │ ├── enc-base64.js │ ├── hmac.js │ ├── sha256.js │ ├── hmac-sha256.js │ ├── apigClient.js │ ├── sigV4Client.js │ ├── url-template.js │ └── axios.standalone.js ├── scripts.js ├── imageTools.js └── fancybox.js ├── index.html └── README.md /Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deeparteffects/deepart-api-html-js-example/HEAD/Screenshot.png -------------------------------------------------------------------------------- /img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deeparteffects/deepart-api-html-js-example/HEAD/img/loading.gif -------------------------------------------------------------------------------- /css/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #fff; 3 | # color: #673ab7; 4 | color: #111; 5 | font-family: Sans-serif; 6 | } 7 | 8 | #progress-wrapper { 9 | width: 350px; 10 | margin: auto; 11 | } 12 | 13 | #qualitySelect { 14 | margin: 15px; 15 | } 16 | 17 | #progressbar { 18 | margin: 25px; 19 | } 20 | 21 | .result-image { 22 | margin: 5px; 23 | } 24 | 25 | .container { 26 | margin: auto; 27 | width: 768px; 28 | padding: 10px; 29 | text-align: center; 30 | } 31 | 32 | .result-image { 33 | width: 125px; 34 | border:1px solid #333333; 35 | } 36 | 37 | .style { 38 | width: 125px; 39 | height: 125px; 40 | background-size: cover; 41 | background-position: center center; 42 | background-repeat: no-repeat; 43 | margin: 8px; 44 | border:1px solid #333333; 45 | } 46 | 47 | #selectable { 48 | list-style-type: none; 49 | list-style: none; 50 | } 51 | 52 | #selectable li { 53 | display: inline; 54 | } 55 | 56 | #selectable div { 57 | float: left; 58 | } -------------------------------------------------------------------------------- /js/client/apiGatewayClient.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | var apiGateway = apiGateway || {}; 17 | apiGateway.core = apiGateway.core || {}; 18 | 19 | apiGateway.core.apiGatewayClientFactory = {}; 20 | apiGateway.core.apiGatewayClientFactory.newClient = function (simpleHttpClientConfig, sigV4ClientConfig) { 21 | var apiGatewayClient = { }; 22 | //Spin up 2 httpClients, one for simple requests, one for SigV4 23 | var sigV4Client = apiGateway.core.sigV4ClientFactory.newClient(sigV4ClientConfig); 24 | var simpleHttpClient = apiGateway.core.simpleHttpClientFactory.newClient(simpleHttpClientConfig); 25 | 26 | apiGatewayClient.makeRequest = function (request, authType, additionalParams, apiKey) { 27 | //Default the request to use the simple http client 28 | var clientToUse = simpleHttpClient; 29 | 30 | //Attach the apiKey to the headers request if one was provided 31 | if (apiKey !== undefined && apiKey !== '' && apiKey !== null) { 32 | request.headers['x-api-key'] = apiKey; 33 | } 34 | 35 | if (request.body === undefined || request.body === '' || request.body === null || Object.keys(request.body).length === 0) { 36 | request.body = undefined; 37 | } 38 | 39 | // If the user specified any additional headers or query params that may not have been modeled 40 | // merge them into the appropriate request properties 41 | request.headers = apiGateway.core.utils.mergeInto(request.headers, additionalParams.headers); 42 | request.queryParams = apiGateway.core.utils.mergeInto(request.queryParams, additionalParams.queryParams); 43 | 44 | //If an auth type was specified inject the appropriate auth client 45 | if (authType === 'AWS_IAM') { 46 | clientToUse = sigV4Client; 47 | } 48 | 49 | //Call the selected http client to make the request, returning a promise once the request is sent 50 | return clientToUse.makeRequest(request); 51 | }; 52 | return apiGatewayClient; 53 | }; 54 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Deep Art Effects Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |

Deep Art Effects - Turn Image Into Art

16 |
17 |

Your artworks

18 |
19 |
20 |

1. Choose picture and quality

21 | 26 | 30 | 34 |
35 | 36 |
37 |
38 | loading 39 |
40 |
41 |

2. Choose art style

42 |
43 |
44 |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /js/client/utils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | var apiGateway = apiGateway || {}; 17 | apiGateway.core = apiGateway.core || {}; 18 | 19 | apiGateway.core.utils = { 20 | assertDefined: function (object, name) { 21 | if (object === undefined) { 22 | throw name + ' must be defined'; 23 | } else { 24 | return object; 25 | } 26 | }, 27 | assertParametersDefined: function (params, keys, ignore) { 28 | if (keys === undefined) { 29 | return; 30 | } 31 | if (keys.length > 0 && params === undefined) { 32 | params = {}; 33 | } 34 | for (var i = 0; i < keys.length; i++) { 35 | if(!apiGateway.core.utils.contains(ignore, keys[i])) { 36 | apiGateway.core.utils.assertDefined(params[keys[i]], keys[i]); 37 | } 38 | } 39 | }, 40 | parseParametersToObject: function (params, keys) { 41 | if (params === undefined) { 42 | return {}; 43 | } 44 | var object = { }; 45 | for (var i = 0; i < keys.length; i++) { 46 | object[keys[i]] = params[keys[i]]; 47 | } 48 | return object; 49 | }, 50 | contains: function(a, obj) { 51 | if(a === undefined) { return false;} 52 | var i = a.length; 53 | while (i--) { 54 | if (a[i] === obj) { 55 | return true; 56 | } 57 | } 58 | return false; 59 | }, 60 | copy: function (obj) { 61 | if (null == obj || "object" != typeof obj) return obj; 62 | var copy = obj.constructor(); 63 | for (var attr in obj) { 64 | if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr]; 65 | } 66 | return copy; 67 | }, 68 | mergeInto: function (baseObj, additionalProps) { 69 | if (null == baseObj || "object" != typeof baseObj) return baseObj; 70 | var merged = baseObj.constructor(); 71 | for (var attr in baseObj) { 72 | if (baseObj.hasOwnProperty(attr)) merged[attr] = baseObj[attr]; 73 | } 74 | if (null == additionalProps || "object" != typeof additionalProps) return baseObj; 75 | for (attr in additionalProps) { 76 | if (additionalProps.hasOwnProperty(attr)) merged[attr] = additionalProps[attr]; 77 | } 78 | return merged; 79 | } 80 | }; 81 | -------------------------------------------------------------------------------- /js/client/simpleHttpClient.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | var apiGateway = apiGateway || {}; 17 | apiGateway.core = apiGateway.core || {}; 18 | 19 | apiGateway.core.simpleHttpClientFactory = {}; 20 | apiGateway.core.simpleHttpClientFactory.newClient = function (config) { 21 | function buildCanonicalQueryString(queryParams) { 22 | //Build a properly encoded query string from a QueryParam object 23 | if (Object.keys(queryParams).length < 1) { 24 | return ''; 25 | } 26 | 27 | var canonicalQueryString = ''; 28 | for (var property in queryParams) { 29 | if (queryParams.hasOwnProperty(property)) { 30 | canonicalQueryString += encodeURIComponent(property) + '=' + encodeURIComponent(queryParams[property]) + '&'; 31 | } 32 | } 33 | 34 | return canonicalQueryString.substr(0, canonicalQueryString.length - 1); 35 | } 36 | 37 | var simpleHttpClient = { }; 38 | simpleHttpClient.endpoint = apiGateway.core.utils.assertDefined(config.endpoint, 'endpoint'); 39 | 40 | simpleHttpClient.makeRequest = function (request) { 41 | var verb = apiGateway.core.utils.assertDefined(request.verb, 'verb'); 42 | var path = apiGateway.core.utils.assertDefined(request.path, 'path'); 43 | var queryParams = apiGateway.core.utils.copy(request.queryParams); 44 | if (queryParams === undefined) { 45 | queryParams = {}; 46 | } 47 | var headers = apiGateway.core.utils.copy(request.headers); 48 | if (headers === undefined) { 49 | headers = {}; 50 | } 51 | 52 | //If the user has not specified an override for Content type the use default 53 | if(headers['Content-Type'] === undefined) { 54 | headers['Content-Type'] = config.defaultContentType; 55 | } 56 | 57 | //If the user has not specified an override for Accept type the use default 58 | if(headers['Accept'] === undefined) { 59 | headers['Accept'] = config.defaultAcceptType; 60 | } 61 | 62 | var body = apiGateway.core.utils.copy(request.body); 63 | if (body === undefined) { 64 | body = ''; 65 | } 66 | 67 | var url = config.endpoint + path; 68 | var queryString = buildCanonicalQueryString(queryParams); 69 | if (queryString != '') { 70 | url += '?' + queryString; 71 | } 72 | var simpleHttpRequest = { 73 | method: verb, 74 | url: url, 75 | headers: headers, 76 | data: body 77 | }; 78 | return axios(simpleHttpRequest); 79 | }; 80 | return simpleHttpClient; 81 | }; -------------------------------------------------------------------------------- /js/scripts.js: -------------------------------------------------------------------------------- 1 | var imageBinary; 2 | var styles; 3 | var resultCheck; 4 | var submissionId; 5 | var maxImageSize; 6 | 7 | var deepArtEffectsClient = apigClientFactory.newClient({ 8 | apiKey: '--INSERT YOUR API KEY--', 9 | accessKey: '--INSERT YOUR ACCESS KEY--', 10 | secretKey: '--INSERT YOUR SECRET KEY--' 11 | }); 12 | 13 | $(document).ready(function(){ 14 | $("#result").hide(); 15 | $("#progress-wrapper").hide(); 16 | deepArtEffectsClient.stylesGet() 17 | .then(function(result){ 18 | console.log("Successfully loaded styles"); 19 | //This is where you would put a success callback 20 | var ol = $('
    '); 21 | ol.appendTo('#style-list') 22 | styles = result.data; 23 | for (var i = 0, length = styles.length; i < length; i++) { 24 | var li = $("
  1. "); 25 | li.attr('onClick',"uploadImage('"+styles[i].id+"')") 26 | var div = $('
    '); 27 | div.attr('style', "background-image: url("+styles[i].url+")"); 28 | li.append(div); 29 | li.appendTo('#selectable'); 30 | } 31 | }).catch(function(result){ 32 | //This is where you would put an error callback 33 | console.log("Error loading styles"); 34 | }); 35 | }) 36 | function uploadImage(styleId) { 37 | if(imageBinary==null) { 38 | alert('Please choose a picture first') 39 | return; 40 | } 41 | 42 | $("#styles").hide(); 43 | $("#progress-wrapper").show(); 44 | maxImageSize = $("#qualitySelect").val(); 45 | 46 | optimizeForPrint = $('#optimzeForPrint').prop('checked'); 47 | useOriginalColors = $('#useOriginalColors').prop('checked'); 48 | 49 | var body = { 50 | 'styleId': styleId, 51 | 'imageBase64Encoded': imageBinary, 52 | 'optimizeForPrint': optimizeForPrint, 53 | 'useOriginalColors': useOriginalColors, 54 | 'imageSize': maxImageSize 55 | }; 56 | 57 | deepArtEffectsClient.uploadPost(null, body) 58 | .then(function(result) { 59 | console.log("Successfully uploaded image"); 60 | submissionId = result.data.submissionId 61 | resultCheck = setInterval(imageReadyCheck, 2500); 62 | }).catch(function(result){ 63 | //This is where you would put an error callback 64 | console.log("Error uploading image"); 65 | }); 66 | } 67 | function imageReadyCheck() { 68 | var params = { 69 | submissionId: submissionId, 70 | }; 71 | deepArtEffectsClient.resultGet(params) 72 | .then(function(result) { 73 | console.log("Successfully status check"); 74 | if(result.data.status=="finished") { 75 | var a = $(''); 76 | a.attr('href', result.data.url); 77 | var img = $(''); 78 | img.attr('src', result.data.url); 79 | a.append(img); 80 | a.appendTo('#artwork'); 81 | clearInterval(resultCheck); 82 | $("#result").show(); 83 | $("#styles").show(); 84 | $("#progress-wrapper").hide(); 85 | } 86 | }).catch(function(result){ 87 | console.log("Error checking status"); 88 | }); 89 | } 90 | function onFileSelected(event) { 91 | var files = event.target.files; 92 | var file = files[0]; 93 | 94 | maxImageSize = $("#qualitySelect").val(); 95 | 96 | if (files && file) { 97 | ImageTools.resize(file, {width: maxImageSize, height: maxImageSize}, 98 | function(blob, didItResize) { 99 | var reader = new FileReader(); 100 | reader.onload = function(readerEvt) { 101 | imageBinary = btoa(readerEvt.target.result); 102 | }; 103 | reader.readAsBinaryString(blob); 104 | } 105 | ); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deep Art Effects API Example For JavaScript 2 | Here is an example on how you can use the Deep Art Effects API for JavaScript to 3 | display available styles, upload an image and get the result. 4 | 5 | If you want to try out the example, change the values for the apiKey, accessKey 6 | and secretKey in `js\scripts.js` to your key values. 7 | 8 | 0 9 | 10 | ## 1. Add dependencies to your website 11 | ```javascript 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ``` 24 | 25 | ## 2. Get a client instance 26 | First of all create an Deep Art Effects Client instance and insert your API-Key, 27 | your Access-Key and your Secret-Key. 28 | 29 | ```javascript 30 | var deepArtEffectsClient = apigClientFactory.newClient({ 31 | apiKey: '--INSERT YOUR API KEY--', 32 | accessKey: '--INSERT YOUR ACCESS KEY--', 33 | secretKey: '--INSERT YOUR SECRET KEY--', 34 | }); 35 | ``` 36 | 37 | ## 3. Get a list of available styles 38 | Next you want get a list of available styles using the stylesGet method. You 39 | get the id and a URL to an image representing the style. 40 | 41 | ```javascript 42 | deepArtEffectsClient.stylesGet() 43 | .then(function(result){ 44 | console.log("Successfully loaded styles"); 45 | styles = result.data; 46 | for (var i = 0, length = styles.length; i < length; i++) { 47 | console.log("StyleId: " + styles[i].id + ", URL: " + styles[i].url); 48 | } 49 | }).catch(function(result){ 50 | console.log("Error loading styles"); 51 | }); 52 | ``` 53 | 54 | ## 4. Upload an image 55 | To upload an image set the styleId you want and hand over the image binary data 56 | converted to Base64. In JavaScript you can convert data to Base64 using the 57 | btoa() function. After uploading the image you get a submissionId to check for 58 | the result. 59 | ```javascript 60 | var params = { 61 | styleId: styleId, 62 | }; 63 | deepArtEffectsClient.uploadPost(params, base64ConvertedImage) 64 | .then(function(result) { 65 | console.log("Successfully uploaded image"); 66 | console.log("SubmissionId: " + result.data.submissionId 67 | }).catch(function(result){ 68 | console.log("Error uploading image"); 69 | }); 70 | ``` 71 | 72 | ## 5. Check for the result 73 | You can pass the submissionId to the resultGet function in order to receive a 74 | status for your submission. If your submission is in `finished` state, you can 75 | use the URL to download your artwork. 76 | ```javascript 77 | var params = { 78 | submissionId: submissionId, 79 | }; 80 | deepArtEffectsClient.resultGet(params) 81 | .then(function(result) { 82 | console.log("Successfully checked status"); 83 | if(result.data.status=="finished") { 84 | console.log("URL for artwork: " + result.data.url) 85 | } 86 | }).catch(function(result){ 87 | console.log("Error checking status"); 88 | }); 89 | ``` 90 | -------------------------------------------------------------------------------- /js/client/enc-base64.js: -------------------------------------------------------------------------------- 1 | /* 2 | CryptoJS v3.1.2 3 | code.google.com/p/crypto-js 4 | (c) 2009-2013 by Jeff Mott. All rights reserved. 5 | code.google.com/p/crypto-js/wiki/License 6 | */ 7 | (function () { 8 | // Shortcuts 9 | var C = CryptoJS; 10 | var C_lib = C.lib; 11 | var WordArray = C_lib.WordArray; 12 | var C_enc = C.enc; 13 | 14 | /** 15 | * Base64 encoding strategy. 16 | */ 17 | var Base64 = C_enc.Base64 = { 18 | /** 19 | * Converts a word array to a Base64 string. 20 | * 21 | * @param {WordArray} wordArray The word array. 22 | * 23 | * @return {string} The Base64 string. 24 | * 25 | * @static 26 | * 27 | * @example 28 | * 29 | * var base64String = CryptoJS.enc.Base64.stringify(wordArray); 30 | */ 31 | stringify: function (wordArray) { 32 | // Shortcuts 33 | var words = wordArray.words; 34 | var sigBytes = wordArray.sigBytes; 35 | var map = this._map; 36 | 37 | // Clamp excess bits 38 | wordArray.clamp(); 39 | 40 | // Convert 41 | var base64Chars = []; 42 | for (var i = 0; i < sigBytes; i += 3) { 43 | var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; 44 | var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; 45 | var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; 46 | 47 | var triplet = (byte1 << 16) | (byte2 << 8) | byte3; 48 | 49 | for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { 50 | base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); 51 | } 52 | } 53 | 54 | // Add padding 55 | var paddingChar = map.charAt(64); 56 | if (paddingChar) { 57 | while (base64Chars.length % 4) { 58 | base64Chars.push(paddingChar); 59 | } 60 | } 61 | 62 | return base64Chars.join(''); 63 | }, 64 | 65 | /** 66 | * Converts a Base64 string to a word array. 67 | * 68 | * @param {string} base64Str The Base64 string. 69 | * 70 | * @return {WordArray} The word array. 71 | * 72 | * @static 73 | * 74 | * @example 75 | * 76 | * var wordArray = CryptoJS.enc.Base64.parse(base64String); 77 | */ 78 | parse: function (base64Str) { 79 | // Shortcuts 80 | var base64StrLength = base64Str.length; 81 | var map = this._map; 82 | 83 | // Ignore padding 84 | var paddingChar = map.charAt(64); 85 | if (paddingChar) { 86 | var paddingIndex = base64Str.indexOf(paddingChar); 87 | if (paddingIndex != -1) { 88 | base64StrLength = paddingIndex; 89 | } 90 | } 91 | 92 | // Convert 93 | var words = []; 94 | var nBytes = 0; 95 | for (var i = 0; i < base64StrLength; i++) { 96 | if (i % 4) { 97 | var bits1 = map.indexOf(base64Str.charAt(i - 1)) << ((i % 4) * 2); 98 | var bits2 = map.indexOf(base64Str.charAt(i)) >>> (6 - (i % 4) * 2); 99 | words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8); 100 | nBytes++; 101 | } 102 | } 103 | 104 | return WordArray.create(words, nBytes); 105 | }, 106 | 107 | _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' 108 | }; 109 | }()); 110 | -------------------------------------------------------------------------------- /js/client/hmac.js: -------------------------------------------------------------------------------- 1 | /* 2 | CryptoJS v3.1.2 3 | code.google.com/p/crypto-js 4 | (c) 2009-2013 by Jeff Mott. All rights reserved. 5 | code.google.com/p/crypto-js/wiki/License 6 | */ 7 | (function () { 8 | // Shortcuts 9 | var C = CryptoJS; 10 | var C_lib = C.lib; 11 | var Base = C_lib.Base; 12 | var C_enc = C.enc; 13 | var Utf8 = C_enc.Utf8; 14 | var C_algo = C.algo; 15 | 16 | /** 17 | * HMAC algorithm. 18 | */ 19 | var HMAC = C_algo.HMAC = Base.extend({ 20 | /** 21 | * Initializes a newly created HMAC. 22 | * 23 | * @param {Hasher} hasher The hash algorithm to use. 24 | * @param {WordArray|string} key The secret key. 25 | * 26 | * @example 27 | * 28 | * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key); 29 | */ 30 | init: function (hasher, key) { 31 | // Init hasher 32 | hasher = this._hasher = new hasher.init(); 33 | 34 | // Convert string to WordArray, else assume WordArray already 35 | if (typeof key == 'string') { 36 | key = Utf8.parse(key); 37 | } 38 | 39 | // Shortcuts 40 | var hasherBlockSize = hasher.blockSize; 41 | var hasherBlockSizeBytes = hasherBlockSize * 4; 42 | 43 | // Allow arbitrary length keys 44 | if (key.sigBytes > hasherBlockSizeBytes) { 45 | key = hasher.finalize(key); 46 | } 47 | 48 | // Clamp excess bits 49 | key.clamp(); 50 | 51 | // Clone key for inner and outer pads 52 | var oKey = this._oKey = key.clone(); 53 | var iKey = this._iKey = key.clone(); 54 | 55 | // Shortcuts 56 | var oKeyWords = oKey.words; 57 | var iKeyWords = iKey.words; 58 | 59 | // XOR keys with pad constants 60 | for (var i = 0; i < hasherBlockSize; i++) { 61 | oKeyWords[i] ^= 0x5c5c5c5c; 62 | iKeyWords[i] ^= 0x36363636; 63 | } 64 | oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes; 65 | 66 | // Set initial values 67 | this.reset(); 68 | }, 69 | 70 | /** 71 | * Resets this HMAC to its initial state. 72 | * 73 | * @example 74 | * 75 | * hmacHasher.reset(); 76 | */ 77 | reset: function () { 78 | // Shortcut 79 | var hasher = this._hasher; 80 | 81 | // Reset 82 | hasher.reset(); 83 | hasher.update(this._iKey); 84 | }, 85 | 86 | /** 87 | * Updates this HMAC with a message. 88 | * 89 | * @param {WordArray|string} messageUpdate The message to append. 90 | * 91 | * @return {HMAC} This HMAC instance. 92 | * 93 | * @example 94 | * 95 | * hmacHasher.update('message'); 96 | * hmacHasher.update(wordArray); 97 | */ 98 | update: function (messageUpdate) { 99 | this._hasher.update(messageUpdate); 100 | 101 | // Chainable 102 | return this; 103 | }, 104 | 105 | /** 106 | * Finalizes the HMAC computation. 107 | * Note that the finalize operation is effectively a destructive, read-once operation. 108 | * 109 | * @param {WordArray|string} messageUpdate (Optional) A final message update. 110 | * 111 | * @return {WordArray} The HMAC. 112 | * 113 | * @example 114 | * 115 | * var hmac = hmacHasher.finalize(); 116 | * var hmac = hmacHasher.finalize('message'); 117 | * var hmac = hmacHasher.finalize(wordArray); 118 | */ 119 | finalize: function (messageUpdate) { 120 | // Shortcut 121 | var hasher = this._hasher; 122 | 123 | // Compute HMAC 124 | var innerHash = hasher.finalize(messageUpdate); 125 | hasher.reset(); 126 | var hmac = hasher.finalize(this._oKey.clone().concat(innerHash)); 127 | 128 | return hmac; 129 | } 130 | }); 131 | }()); 132 | -------------------------------------------------------------------------------- /js/client/sha256.js: -------------------------------------------------------------------------------- 1 | /* 2 | CryptoJS v3.1.2 3 | code.google.com/p/crypto-js 4 | (c) 2009-2013 by Jeff Mott. All rights reserved. 5 | code.google.com/p/crypto-js/wiki/License 6 | */ 7 | var CryptoJS=CryptoJS||function(h,s){var f={},t=f.lib={},g=function(){},j=t.Base={extend:function(a){g.prototype=this;var c=new g;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, 8 | q=t.WordArray=j.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=s?c:4*a.length},toString:function(a){return(a||u).stringify(this)},concat:function(a){var c=this.words,d=a.words,b=this.sigBytes;a=a.sigBytes;this.clamp();if(b%4)for(var e=0;e>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((b+e)%4);else if(65535>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< 9 | 32-8*(c%4);a.length=h.ceil(c/4)},clone:function(){var a=j.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d>>2]>>>24-8*(b%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b>>3]|=parseInt(a.substr(b, 10 | 2),16)<<24-4*(b%8);return new q.init(d,c/2)}},k=v.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b>>2]>>>24-8*(b%4)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%4);return new q.init(d,c)}},l=v.Utf8={stringify:function(a){try{return decodeURIComponent(escape(k.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return k.parse(unescape(encodeURIComponent(a)))}}, 11 | x=t.BufferedBlockAlgorithm=j.extend({reset:function(){this._data=new q.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=l.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;b=h.min(4*a,b);if(a){for(var m=0;mk;){var l;a:{l=u;for(var x=h.sqrt(l),w=2;w<=x;w++)if(!(l%w)){l=!1;break a}l=!0}l&&(8>k&&(j[k]=v(h.pow(u,0.5))),q[k]=v(h.pow(u,1/3)),k++);u++}var a=[],f=f.SHA256=g.extend({_doReset:function(){this._hash=new t.init(j.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],m=b[2],h=b[3],p=b[4],j=b[5],k=b[6],l=b[7],n=0;64>n;n++){if(16>n)a[n]= 15 | c[d+n]|0;else{var r=a[n-15],g=a[n-2];a[n]=((r<<25|r>>>7)^(r<<14|r>>>18)^r>>>3)+a[n-7]+((g<<15|g>>>17)^(g<<13|g>>>19)^g>>>10)+a[n-16]}r=l+((p<<26|p>>>6)^(p<<21|p>>>11)^(p<<7|p>>>25))+(p&j^~p&k)+q[n]+a[n];g=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&m^f&m);l=k;k=j;j=p;p=h+r|0;h=m;m=f;f=e;e=r+g|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+m|0;b[3]=b[3]+h|0;b[4]=b[4]+p|0;b[5]=b[5]+j|0;b[6]=b[6]+k|0;b[7]=b[7]+l|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes; 16 | d[e>>>5]|=128<<24-e%32;d[(e+64>>>9<<4)+14]=h.floor(b/4294967296);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=g.clone.call(this);a._hash=this._hash.clone();return a}});s.SHA256=g._createHelper(f);s.HmacSHA256=g._createHmacHelper(f)})(Math); 17 | -------------------------------------------------------------------------------- /js/client/hmac-sha256.js: -------------------------------------------------------------------------------- 1 | /* 2 | CryptoJS v3.1.2 3 | code.google.com/p/crypto-js 4 | (c) 2009-2013 by Jeff Mott. All rights reserved. 5 | code.google.com/p/crypto-js/wiki/License 6 | */ 7 | var CryptoJS=CryptoJS||function(h,s){var f={},g=f.lib={},q=function(){},m=g.Base={extend:function(a){q.prototype=this;var c=new q;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, 8 | r=g.WordArray=m.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=s?c:4*a.length},toString:function(a){return(a||k).stringify(this)},concat:function(a){var c=this.words,d=a.words,b=this.sigBytes;a=a.sigBytes;this.clamp();if(b%4)for(var e=0;e>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((b+e)%4);else if(65535>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< 9 | 32-8*(c%4);a.length=h.ceil(c/4)},clone:function(){var a=m.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d>>2]>>>24-8*(b%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b>>3]|=parseInt(a.substr(b, 10 | 2),16)<<24-4*(b%8);return new r.init(d,c/2)}},n=l.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b>>2]>>>24-8*(b%4)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%4);return new r.init(d,c)}},j=l.Utf8={stringify:function(a){try{return decodeURIComponent(escape(n.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return n.parse(unescape(encodeURIComponent(a)))}}, 11 | u=g.BufferedBlockAlgorithm=m.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=j.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;b=h.min(4*a,b);if(a){for(var g=0;gn;){var j;a:{j=k;for(var u=h.sqrt(j),t=2;t<=u;t++)if(!(j%t)){j=!1;break a}j=!0}j&&(8>n&&(m[n]=l(h.pow(k,0.5))),r[n]=l(h.pow(k,1/3)),n++);k++}var a=[],f=f.SHA256=q.extend({_doReset:function(){this._hash=new g.init(m.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],g=b[2],j=b[3],h=b[4],m=b[5],n=b[6],q=b[7],p=0;64>p;p++){if(16>p)a[p]= 15 | c[d+p]|0;else{var k=a[p-15],l=a[p-2];a[p]=((k<<25|k>>>7)^(k<<14|k>>>18)^k>>>3)+a[p-7]+((l<<15|l>>>17)^(l<<13|l>>>19)^l>>>10)+a[p-16]}k=q+((h<<26|h>>>6)^(h<<21|h>>>11)^(h<<7|h>>>25))+(h&m^~h&n)+r[p]+a[p];l=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&g^f&g);q=n;n=m;m=h;h=j+k|0;j=g;g=f;f=e;e=k+l|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+g|0;b[3]=b[3]+j|0;b[4]=b[4]+h|0;b[5]=b[5]+m|0;b[6]=b[6]+n|0;b[7]=b[7]+q|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes; 16 | d[e>>>5]|=128<<24-e%32;d[(e+64>>>9<<4)+14]=h.floor(b/4294967296);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=q.clone.call(this);a._hash=this._hash.clone();return a}});s.SHA256=q._createHelper(f);s.HmacSHA256=q._createHmacHelper(f)})(Math); 17 | (function(){var h=CryptoJS,s=h.enc.Utf8;h.algo.HMAC=h.lib.Base.extend({init:function(f,g){f=this._hasher=new f.init;"string"==typeof g&&(g=s.parse(g));var h=f.blockSize,m=4*h;g.sigBytes>m&&(g=f.finalize(g));g.clamp();for(var r=this._oKey=g.clone(),l=this._iKey=g.clone(),k=r.words,n=l.words,j=0;j height && width > maxDimensions.width) { 80 | // width is the largest dimension, and it's too big. 81 | height *= maxDimensions.width / width; 82 | width = maxDimensions.width; 83 | isTooLarge = true; 84 | } else if (height > maxDimensions.height) { 85 | // either width wasn't over-size or height is the largest dimension 86 | // and the height is over-size 87 | width *= maxDimensions.height / height; 88 | height = maxDimensions.height; 89 | isTooLarge = true; 90 | } 91 | 92 | if (!isTooLarge) { 93 | // early exit; no need to resize 94 | callback(file, false); 95 | return; 96 | } 97 | 98 | var canvas = document.createElement('canvas'); 99 | canvas.width = width; 100 | canvas.height = height; 101 | 102 | var ctx = canvas.getContext('2d'); 103 | ctx.drawImage(image, 0, 0, width, height); 104 | 105 | if (hasToBlobSupport) { 106 | canvas.toBlob(function (blob) { 107 | callback(blob, true); 108 | }, file.type); 109 | } else { 110 | var blob = ImageTools._toBlob(canvas, file.type); 111 | callback(blob, true); 112 | } 113 | }; 114 | ImageTools._loadImage(image, file); 115 | 116 | return true; 117 | } 118 | }, { 119 | key: '_toBlob', 120 | value: function _toBlob(canvas, type) { 121 | var dataURI = canvas.toDataURL(type); 122 | var dataURIParts = dataURI.split(','); 123 | var byteString = undefined; 124 | if (dataURIParts[0].indexOf('base64') >= 0) { 125 | // Convert base64 to raw binary data held in a string: 126 | byteString = atob(dataURIParts[1]); 127 | } else { 128 | // Convert base64/URLEncoded data component to raw binary data: 129 | byteString = decodeURIComponent(dataURIParts[1]); 130 | } 131 | var arrayBuffer = new ArrayBuffer(byteString.length); 132 | var intArray = new Uint8Array(arrayBuffer); 133 | 134 | for (var i = 0; i < byteString.length; i += 1) { 135 | intArray[i] = byteString.charCodeAt(i); 136 | } 137 | 138 | var mimeString = dataURIParts[0].split(':')[1].split(';')[0]; 139 | var blob = null; 140 | 141 | if (hasBlobConstructor) { 142 | blob = new Blob([hasArrayBufferViewSupport ? intArray : arrayBuffer], { type: mimeString }); 143 | } else { 144 | var bb = new BlobBuilder(); 145 | bb.append(arrayBuffer); 146 | blob = bb.getBlob(mimeString); 147 | } 148 | 149 | return blob; 150 | } 151 | }, { 152 | key: '_loadImage', 153 | value: function _loadImage(image, file, callback) { 154 | if (typeof URL === 'undefined') { 155 | var reader = new FileReader(); 156 | reader.onload = function (evt) { 157 | image.src = evt.target.result; 158 | if (callback) { 159 | callback(); 160 | } 161 | }; 162 | reader.readAsDataURL(file); 163 | } else { 164 | image.src = URL.createObjectURL(file); 165 | if (callback) { 166 | callback(); 167 | } 168 | } 169 | } 170 | }, { 171 | key: 'isSupported', 172 | value: function isSupported() { 173 | return typeof HTMLCanvasElement !== 'undefined' && hasBlobSupport && hasReaderSupport; 174 | } 175 | }]); 176 | 177 | return ImageTools; 178 | })(); 179 | 180 | exports['default'] = ImageTools; 181 | module.exports = exports['default']; -------------------------------------------------------------------------------- /js/client/apigClient.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | var apigClientFactory = {}; 17 | apigClientFactory.newClient = function (config) { 18 | var apigClient = { }; 19 | if(config === undefined) { 20 | config = { 21 | accessKey: '', 22 | secretKey: '', 23 | sessionToken: '', 24 | region: '', 25 | apiKey: undefined, 26 | defaultContentType: 'application/json', 27 | defaultAcceptType: 'application/json' 28 | }; 29 | } 30 | if(config.accessKey === undefined) { 31 | config.accessKey = ''; 32 | } 33 | if(config.secretKey === undefined) { 34 | config.secretKey = ''; 35 | } 36 | if(config.apiKey === undefined) { 37 | config.apiKey = ''; 38 | } 39 | if(config.sessionToken === undefined) { 40 | config.sessionToken = ''; 41 | } 42 | if(config.region === undefined) { 43 | config.region = 'eu-west-1'; 44 | } 45 | //If defaultContentType is not defined then default to application/json 46 | if(config.defaultContentType === undefined) { 47 | config.defaultContentType = 'application/json'; 48 | } 49 | //If defaultAcceptType is not defined then default to application/json 50 | if(config.defaultAcceptType === undefined) { 51 | config.defaultAcceptType = 'application/json'; 52 | } 53 | 54 | 55 | // extract endpoint and path from url 56 | var invokeUrl = 'https://api.deeparteffects.com/v1'; 57 | var endpoint = /(^https?:\/\/[^\/]+)/g.exec(invokeUrl)[1]; 58 | var pathComponent = invokeUrl.substring(endpoint.length); 59 | 60 | var sigV4ClientConfig = { 61 | accessKey: config.accessKey, 62 | secretKey: config.secretKey, 63 | sessionToken: config.sessionToken, 64 | serviceName: 'execute-api', 65 | region: config.region, 66 | endpoint: endpoint, 67 | defaultContentType: config.defaultContentType, 68 | defaultAcceptType: config.defaultAcceptType 69 | }; 70 | 71 | var authType = 'NONE'; 72 | if (sigV4ClientConfig.accessKey !== undefined && sigV4ClientConfig.accessKey !== '' && sigV4ClientConfig.secretKey !== undefined && sigV4ClientConfig.secretKey !== '') { 73 | authType = 'AWS_IAM'; 74 | } 75 | 76 | var simpleHttpClientConfig = { 77 | endpoint: endpoint, 78 | defaultContentType: config.defaultContentType, 79 | defaultAcceptType: config.defaultAcceptType 80 | }; 81 | 82 | var apiGatewayClient = apiGateway.core.apiGatewayClientFactory.newClient(simpleHttpClientConfig, sigV4ClientConfig); 83 | 84 | 85 | 86 | apigClient.resultGet = function (params, body, additionalParams) { 87 | if(additionalParams === undefined) { additionalParams = {}; } 88 | 89 | apiGateway.core.utils.assertParametersDefined(params, ['submissionId'], ['body']); 90 | 91 | var resultGetRequest = { 92 | verb: 'get'.toUpperCase(), 93 | path: pathComponent + uritemplate('/result').expand(apiGateway.core.utils.parseParametersToObject(params, [])), 94 | headers: apiGateway.core.utils.parseParametersToObject(params, []), 95 | queryParams: apiGateway.core.utils.parseParametersToObject(params, ['submissionId']), 96 | body: body 97 | }; 98 | 99 | 100 | return apiGatewayClient.makeRequest(resultGetRequest, authType, additionalParams, config.apiKey); 101 | }; 102 | 103 | 104 | apigClient.resultOptions = function (params, body, additionalParams) { 105 | if(additionalParams === undefined) { additionalParams = {}; } 106 | 107 | apiGateway.core.utils.assertParametersDefined(params, [], ['body']); 108 | 109 | var resultOptionsRequest = { 110 | verb: 'options'.toUpperCase(), 111 | path: pathComponent + uritemplate('/result').expand(apiGateway.core.utils.parseParametersToObject(params, [])), 112 | headers: apiGateway.core.utils.parseParametersToObject(params, []), 113 | queryParams: apiGateway.core.utils.parseParametersToObject(params, []), 114 | body: body 115 | }; 116 | 117 | 118 | return apiGatewayClient.makeRequest(resultOptionsRequest, authType, additionalParams, config.apiKey); 119 | }; 120 | 121 | 122 | apigClient.stylesGet = function (params, body, additionalParams) { 123 | if(additionalParams === undefined) { additionalParams = {}; } 124 | 125 | apiGateway.core.utils.assertParametersDefined(params, [], ['body']); 126 | 127 | var stylesGetRequest = { 128 | verb: 'get'.toUpperCase(), 129 | path: pathComponent + uritemplate('/styles').expand(apiGateway.core.utils.parseParametersToObject(params, [])), 130 | headers: apiGateway.core.utils.parseParametersToObject(params, []), 131 | queryParams: apiGateway.core.utils.parseParametersToObject(params, []), 132 | body: body 133 | }; 134 | 135 | 136 | return apiGatewayClient.makeRequest(stylesGetRequest, authType, additionalParams, config.apiKey); 137 | }; 138 | 139 | 140 | apigClient.stylesOptions = function (params, body, additionalParams) { 141 | if(additionalParams === undefined) { additionalParams = {}; } 142 | 143 | apiGateway.core.utils.assertParametersDefined(params, [], ['body']); 144 | 145 | var stylesOptionsRequest = { 146 | verb: 'options'.toUpperCase(), 147 | path: pathComponent + uritemplate('/styles').expand(apiGateway.core.utils.parseParametersToObject(params, [])), 148 | headers: apiGateway.core.utils.parseParametersToObject(params, []), 149 | queryParams: apiGateway.core.utils.parseParametersToObject(params, []), 150 | body: body 151 | }; 152 | 153 | 154 | return apiGatewayClient.makeRequest(stylesOptionsRequest, authType, additionalParams, config.apiKey); 155 | }; 156 | 157 | 158 | apigClient.uploadPost = function (params, body, additionalParams) { 159 | if(additionalParams === undefined) { additionalParams = {}; } 160 | 161 | apiGateway.core.utils.assertParametersDefined(params, ['body'], ['body']); 162 | 163 | var uploadPostRequest = { 164 | verb: 'post'.toUpperCase(), 165 | path: pathComponent + uritemplate('/upload').expand(apiGateway.core.utils.parseParametersToObject(params, [])), 166 | headers: apiGateway.core.utils.parseParametersToObject(params, []), 167 | queryParams: apiGateway.core.utils.parseParametersToObject(params, []), 168 | body: body 169 | }; 170 | 171 | 172 | return apiGatewayClient.makeRequest(uploadPostRequest, authType, additionalParams, config.apiKey); 173 | }; 174 | 175 | 176 | apigClient.uploadOptions = function (params, body, additionalParams) { 177 | if(additionalParams === undefined) { additionalParams = {}; } 178 | 179 | apiGateway.core.utils.assertParametersDefined(params, [], ['body']); 180 | 181 | var uploadOptionsRequest = { 182 | verb: 'options'.toUpperCase(), 183 | path: pathComponent + uritemplate('/upload').expand(apiGateway.core.utils.parseParametersToObject(params, [])), 184 | headers: apiGateway.core.utils.parseParametersToObject(params, []), 185 | queryParams: apiGateway.core.utils.parseParametersToObject(params, []), 186 | body: body 187 | }; 188 | 189 | 190 | return apiGatewayClient.makeRequest(uploadOptionsRequest, authType, additionalParams, config.apiKey); 191 | }; 192 | 193 | 194 | return apigClient; 195 | }; 196 | -------------------------------------------------------------------------------- /js/client/sigV4Client.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | var apiGateway = apiGateway || {}; 17 | apiGateway.core = apiGateway.core || {}; 18 | 19 | apiGateway.core.sigV4ClientFactory = {}; 20 | apiGateway.core.sigV4ClientFactory.newClient = function (config) { 21 | var AWS_SHA_256 = 'AWS4-HMAC-SHA256'; 22 | var AWS4_REQUEST = 'aws4_request'; 23 | var AWS4 = 'AWS4'; 24 | var X_AMZ_DATE = 'x-amz-date'; 25 | var X_AMZ_SECURITY_TOKEN = 'x-amz-security-token'; 26 | var HOST = 'host'; 27 | var AUTHORIZATION = 'Authorization'; 28 | 29 | function hash(value) { 30 | return CryptoJS.SHA256(value); 31 | } 32 | 33 | function hexEncode(value) { 34 | return value.toString(CryptoJS.enc.Hex); 35 | } 36 | 37 | function hmac(secret, value) { 38 | return CryptoJS.HmacSHA256(value, secret, {asBytes: true}); 39 | } 40 | 41 | function buildCanonicalRequest(method, path, queryParams, headers, payload) { 42 | return method + '\n' + 43 | buildCanonicalUri(path) + '\n' + 44 | buildCanonicalQueryString(queryParams) + '\n' + 45 | buildCanonicalHeaders(headers) + '\n' + 46 | buildCanonicalSignedHeaders(headers) + '\n' + 47 | hexEncode(hash(payload)); 48 | } 49 | 50 | function hashCanonicalRequest(request) { 51 | return hexEncode(hash(request)); 52 | } 53 | 54 | function buildCanonicalUri(uri) { 55 | return encodeURI(uri); 56 | } 57 | 58 | function buildCanonicalQueryString(queryParams) { 59 | if (Object.keys(queryParams).length < 1) { 60 | return ''; 61 | } 62 | 63 | var sortedQueryParams = []; 64 | for (var property in queryParams) { 65 | if (queryParams.hasOwnProperty(property)) { 66 | sortedQueryParams.push(property); 67 | } 68 | } 69 | sortedQueryParams.sort(); 70 | 71 | var canonicalQueryString = ''; 72 | for (var i = 0; i < sortedQueryParams.length; i++) { 73 | canonicalQueryString += sortedQueryParams[i] + '=' + fixedEncodeURIComponent(queryParams[sortedQueryParams[i]]) + '&'; 74 | } 75 | return canonicalQueryString.substr(0, canonicalQueryString.length - 1); 76 | } 77 | 78 | function fixedEncodeURIComponent (str) { 79 | return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { 80 | return '%' + c.charCodeAt(0).toString(16); 81 | }); 82 | } 83 | 84 | function buildCanonicalHeaders(headers) { 85 | var canonicalHeaders = ''; 86 | var sortedKeys = []; 87 | for (var property in headers) { 88 | if (headers.hasOwnProperty(property)) { 89 | sortedKeys.push(property); 90 | } 91 | } 92 | sortedKeys.sort(); 93 | 94 | for (var i = 0; i < sortedKeys.length; i++) { 95 | canonicalHeaders += sortedKeys[i].toLowerCase() + ':' + headers[sortedKeys[i]] + '\n'; 96 | } 97 | return canonicalHeaders; 98 | } 99 | 100 | function buildCanonicalSignedHeaders(headers) { 101 | var sortedKeys = []; 102 | for (var property in headers) { 103 | if (headers.hasOwnProperty(property)) { 104 | sortedKeys.push(property.toLowerCase()); 105 | } 106 | } 107 | sortedKeys.sort(); 108 | 109 | return sortedKeys.join(';'); 110 | } 111 | 112 | function buildStringToSign(datetime, credentialScope, hashedCanonicalRequest) { 113 | return AWS_SHA_256 + '\n' + 114 | datetime + '\n' + 115 | credentialScope + '\n' + 116 | hashedCanonicalRequest; 117 | } 118 | 119 | function buildCredentialScope(datetime, region, service) { 120 | return datetime.substr(0, 8) + '/' + region + '/' + service + '/' + AWS4_REQUEST 121 | } 122 | 123 | function calculateSigningKey(secretKey, datetime, region, service) { 124 | return hmac(hmac(hmac(hmac(AWS4 + secretKey, datetime.substr(0, 8)), region), service), AWS4_REQUEST); 125 | } 126 | 127 | function calculateSignature(key, stringToSign) { 128 | return hexEncode(hmac(key, stringToSign)); 129 | } 130 | 131 | function buildAuthorizationHeader(accessKey, credentialScope, headers, signature) { 132 | return AWS_SHA_256 + ' Credential=' + accessKey + '/' + credentialScope + ', SignedHeaders=' + buildCanonicalSignedHeaders(headers) + ', Signature=' + signature; 133 | } 134 | 135 | var awsSigV4Client = { }; 136 | if(config.accessKey === undefined || config.secretKey === undefined) { 137 | return awsSigV4Client; 138 | } 139 | awsSigV4Client.accessKey = apiGateway.core.utils.assertDefined(config.accessKey, 'accessKey'); 140 | awsSigV4Client.secretKey = apiGateway.core.utils.assertDefined(config.secretKey, 'secretKey'); 141 | awsSigV4Client.sessionToken = config.sessionToken; 142 | awsSigV4Client.serviceName = apiGateway.core.utils.assertDefined(config.serviceName, 'serviceName'); 143 | awsSigV4Client.region = apiGateway.core.utils.assertDefined(config.region, 'region'); 144 | awsSigV4Client.endpoint = apiGateway.core.utils.assertDefined(config.endpoint, 'endpoint'); 145 | 146 | awsSigV4Client.makeRequest = function (request) { 147 | var verb = apiGateway.core.utils.assertDefined(request.verb, 'verb'); 148 | var path = apiGateway.core.utils.assertDefined(request.path, 'path'); 149 | var queryParams = apiGateway.core.utils.copy(request.queryParams); 150 | if (queryParams === undefined) { 151 | queryParams = {}; 152 | } 153 | var headers = apiGateway.core.utils.copy(request.headers); 154 | if (headers === undefined) { 155 | headers = {}; 156 | } 157 | 158 | //If the user has not specified an override for Content type the use default 159 | if(headers['Content-Type'] === undefined) { 160 | headers['Content-Type'] = config.defaultContentType; 161 | } 162 | 163 | //If the user has not specified an override for Accept type the use default 164 | if(headers['Accept'] === undefined) { 165 | headers['Accept'] = config.defaultAcceptType; 166 | } 167 | 168 | var body = apiGateway.core.utils.copy(request.body); 169 | if (body === undefined || verb === 'GET') { // override request body and set to empty when signing GET requests 170 | body = ''; 171 | } else { 172 | body = JSON.stringify(body); 173 | } 174 | 175 | //If there is no body remove the content-type header so it is not included in SigV4 calculation 176 | if(body === '' || body === undefined || body === null) { 177 | delete headers['Content-Type']; 178 | } 179 | 180 | var datetime = new Date().toISOString().replace(/\.\d{3}Z$/, 'Z').replace(/[:\-]|\.\d{3}/g, ''); 181 | headers[X_AMZ_DATE] = datetime; 182 | var parser = document.createElement('a'); 183 | parser.href = awsSigV4Client.endpoint; 184 | headers[HOST] = parser.hostname; 185 | 186 | var canonicalRequest = buildCanonicalRequest(verb, path, queryParams, headers, body); 187 | var hashedCanonicalRequest = hashCanonicalRequest(canonicalRequest); 188 | var credentialScope = buildCredentialScope(datetime, awsSigV4Client.region, awsSigV4Client.serviceName); 189 | var stringToSign = buildStringToSign(datetime, credentialScope, hashedCanonicalRequest); 190 | var signingKey = calculateSigningKey(awsSigV4Client.secretKey, datetime, awsSigV4Client.region, awsSigV4Client.serviceName); 191 | var signature = calculateSignature(signingKey, stringToSign); 192 | headers[AUTHORIZATION] = buildAuthorizationHeader(awsSigV4Client.accessKey, credentialScope, headers, signature); 193 | if(awsSigV4Client.sessionToken !== undefined && awsSigV4Client.sessionToken !== '') { 194 | headers[X_AMZ_SECURITY_TOKEN] = awsSigV4Client.sessionToken; 195 | } 196 | delete headers[HOST]; 197 | 198 | var url = config.endpoint + path; 199 | var queryString = buildCanonicalQueryString(queryParams); 200 | if (queryString != '') { 201 | url += '?' + queryString; 202 | } 203 | 204 | //Need to re-attach Content-Type if it is not specified at this point 205 | if(headers['Content-Type'] === undefined) { 206 | headers['Content-Type'] = config.defaultContentType; 207 | } 208 | 209 | var signedRequest = { 210 | method: verb, 211 | url: url, 212 | headers: headers, 213 | data: body 214 | }; 215 | return axios(signedRequest); 216 | }; 217 | 218 | return awsSigV4Client; 219 | }; 220 | -------------------------------------------------------------------------------- /css/fancybox.css: -------------------------------------------------------------------------------- 1 | .fancybox-enabled{overflow:hidden}.fancybox-enabled body{overflow:visible;-ms-touch-action:none;touch-action:none}.fancybox-container{position:fixed;top:0;left:0;width:100%;height:100%;z-index:99993;-webkit-backface-visibility:hidden;backface-visibility:hidden}.fancybox-container~.fancybox-container{z-index:99992}.fancybox-bg{position:absolute;top:0;right:0;bottom:0;left:0;background:#0f0f11;opacity:0;transition-timing-function:cubic-bezier(.55,.06,.68,.19);-webkit-backface-visibility:hidden;backface-visibility:hidden}.fancybox-container--ready .fancybox-bg{opacity:.87;transition-timing-function:cubic-bezier(.22,.61,.36,1)}.fancybox-controls{position:absolute;top:0;left:0;right:0;text-align:center;opacity:0;z-index:99994;transition:opacity .2s;pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;direction:ltr}.fancybox-show-controls .fancybox-controls{opacity:1}.fancybox-infobar{display:none}.fancybox-show-infobar .fancybox-infobar{display:inline-block;pointer-events:all}.fancybox-infobar__body{display:inline-block;width:70px;line-height:44px;font-size:13px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;text-align:center;color:#ddd;background-color:rgba(30,30,30,.7);pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;-webkit-font-smoothing:subpixel-antialiased}.fancybox-buttons{position:absolute;top:0;right:0;display:none;pointer-events:all}.fancybox-show-buttons .fancybox-buttons{display:block}.fancybox-slider-wrap{overflow:hidden;direction:ltr}.fancybox-slider,.fancybox-slider-wrap{position:absolute;top:0;left:0;bottom:0;right:0;padding:0;margin:0;z-index:99993;-webkit-backface-visibility:hidden;backface-visibility:hidden}.fancybox-slide{position:absolute;top:0;left:0;width:100%;height:100%;margin:0;padding:0;overflow:auto;outline:none;white-space:normal;box-sizing:border-box;text-align:center;z-index:99994;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:transparent}.fancybox-slide:before{content:"";height:100%;width:0}.fancybox-slide:before,.fancybox-slide>*{display:inline-block;vertical-align:middle}.fancybox-slide>*{position:relative;padding:24px;margin:44px 0;border-width:0;text-align:left;background-color:#fff;overflow:auto;box-sizing:border-box}.fancybox-slide--image{overflow:hidden}.fancybox-slide--image:before{display:none}.fancybox-content{display:inline-block;position:relative;margin:44px auto;padding:0;border:0;width:80%;height:calc(100% - 88px);vertical-align:middle;line-height:normal;text-align:left;white-space:normal;outline:none;font-size:16px;font-family:Arial,sans-serif;box-sizing:border-box;-webkit-tap-highlight-color:transparent;-webkit-overflow-scrolling:touch}.fancybox-iframe{display:block;margin:0;padding:0;border:0;width:100%;height:100%;background:#fff}.fancybox-slide--video .fancybox-content,.fancybox-slide--video .fancybox-iframe{background:transparent}.fancybox-placeholder{z-index:99995;background:transparent;cursor:default;overflow:visible;-webkit-transform-origin:top left;transform-origin:top left;background-size:100% 100%;background-repeat:no-repeat;-webkit-backface-visibility:hidden;backface-visibility:hidden}.fancybox-image,.fancybox-placeholder,.fancybox-spaceball{position:absolute;top:0;left:0;margin:0;padding:0;border:0}.fancybox-image,.fancybox-spaceball{width:100%;height:100%;max-width:none;max-height:none;background:transparent;background-size:100% 100%}.fancybox-controls--canzoomOut .fancybox-placeholder{cursor:zoom-out}.fancybox-controls--canzoomIn .fancybox-placeholder{cursor:zoom-in}.fancybox-controls--canGrab .fancybox-placeholder{cursor:-webkit-grab;cursor:grab}.fancybox-controls--isGrabbing .fancybox-placeholder{cursor:-webkit-grabbing;cursor:grabbing}.fancybox-spaceball{z-index:1}.fancybox-tmp{position:absolute;top:-9999px;left:-9999px;visibility:hidden}.fancybox-error{position:absolute;margin:0;padding:40px;top:50%;left:50%;width:380px;max-width:100%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);background:#fff;cursor:default}.fancybox-error p{margin:0;padding:0;color:#444;font:16px/20px Helvetica Neue,Helvetica,Arial,sans-serif}.fancybox-close-small{position:absolute;top:4px;right:4px;padding:0;margin:0;width:30px;height:30px;font:21px/1 Arial,Helvetica Neue,Helvetica,sans-serif;color:#888;font-weight:300;text-align:center;border-radius:50%;border-width:0;cursor:pointer;background:#fff;transition:background .2s;box-sizing:border-box;z-index:2}.fancybox-close-small:focus{outline:1px dotted #888}.fancybox-slide--video .fancybox-close-small{top:-36px;right:-36px;background:transparent}.fancybox-close-small:hover{color:#555;background:#eee}.fancybox-caption-wrap{position:absolute;bottom:0;left:0;right:0;padding:60px 30px 0;z-index:99998;-webkit-backface-visibility:hidden;backface-visibility:hidden;box-sizing:border-box;background:linear-gradient(180deg,transparent 0,rgba(0,0,0,.1) 20%,rgba(0,0,0,.2) 40%,rgba(0,0,0,.6) 80%,rgba(0,0,0,.8));opacity:0;transition:opacity .2s;pointer-events:none}.fancybox-show-caption .fancybox-caption-wrap{opacity:1}.fancybox-caption{padding:30px 0;border-top:1px solid hsla(0,0%,100%,.4);font-size:14px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:#fff;line-height:20px;-webkit-text-size-adjust:none}.fancybox-caption a,.fancybox-caption button{pointer-events:all}.fancybox-caption a{color:#fff;text-decoration:underline}.fancybox-button{display:inline-block;position:relative;width:44px;height:44px;line-height:44px;margin:0;padding:0;border:0;border-radius:0;cursor:pointer;background:transparent;color:#fff;box-sizing:border-box;vertical-align:top;outline:none}.fancybox-button--disabled{cursor:default;pointer-events:none}.fancybox-button,.fancybox-infobar__body{background:rgba(30,30,30,.6)}.fancybox-button:hover{background:rgba(0,0,0,.8)}.fancybox-button:after,.fancybox-button:before{content:"";pointer-events:none;position:absolute;border-color:#fff;background-color:currentColor;color:currentColor;opacity:.9;box-sizing:border-box;display:inline-block}.fancybox-button--disabled:after,.fancybox-button--disabled:before{opacity:.5}.fancybox-button--left:after{left:20px;-webkit-transform:rotate(-135deg);transform:rotate(-135deg)}.fancybox-button--left:after,.fancybox-button--right:after{top:18px;width:6px;height:6px;background:transparent;border-top:2px solid currentColor;border-right:2px solid currentColor}.fancybox-button--right:after{right:20px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.fancybox-button--left{border-bottom-left-radius:5px}.fancybox-button--right{border-bottom-right-radius:5px}.fancybox-button--close{float:right}.fancybox-button--close:after,.fancybox-button--close:before{content:"";display:inline-block;position:absolute;height:2px;width:16px;top:calc(50% - 1px);left:calc(50% - 8px)}.fancybox-button--close:before{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.fancybox-button--close:after{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.fancybox-loading{border:6px solid hsla(0,0%,39%,.4);border-top:6px solid hsla(0,0%,100%,.6);border-radius:100%;height:50px;width:50px;-webkit-animation:a .8s infinite linear;animation:a .8s infinite linear;background:transparent;position:absolute;top:50%;left:50%;margin-top:-25px;margin-left:-25px;z-index:99999}@-webkit-keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@media (max-width:800px){.fancybox-controls{text-align:left}.fancybox-button--left,.fancybox-button--right,.fancybox-buttons button:not(.fancybox-button--close){display:none!important}.fancybox-caption{padding:20px 0;margin:0}}.fancybox-button--fullscreen:before{width:15px;height:11px;left:15px;top:16px;border:2px solid;background:none}.fancybox-button--play:before{top:16px;left:18px;width:0;height:0;border-top:6px inset transparent;border-bottom:6px inset transparent;border-left:10px solid;border-radius:1px;background:transparent}.fancybox-button--pause:before{top:16px;left:18px;width:7px;height:11px;border-style:solid;border-width:0 2px;background:transparent}.fancybox-button--thumbs span{font-size:23px}.fancybox-button--thumbs:before{top:20px;left:21px;width:3px;height:3px;box-shadow:0 -4px 0,-4px -4px 0,4px -4px 0,inset 0 0 0 32px,-4px 0 0,4px 0 0,0 4px 0,-4px 4px 0,4px 4px 0}.fancybox-container--thumbs .fancybox-caption-wrap,.fancybox-container--thumbs .fancybox-controls,.fancybox-container--thumbs .fancybox-slider-wrap{right:220px}.fancybox-thumbs{position:absolute;top:0;right:0;bottom:0;left:auto;width:220px;margin:0;padding:5px 5px 0 0;background:#fff;z-index:99993;word-break:normal;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:transparent;box-sizing:border-box}.fancybox-thumbs>ul{list-style:none;position:absolute;position:relative;width:100%;height:100%;margin:0;padding:0;overflow-x:hidden;overflow-y:auto;font-size:0}.fancybox-thumbs>ul>li{float:left;overflow:hidden;max-width:50%;padding:0;margin:0;width:105px;height:75px;position:relative;cursor:pointer;outline:none;border:5px solid #fff;border-top-width:0;border-right-width:0;-webkit-tap-highlight-color:transparent;-webkit-backface-visibility:hidden;backface-visibility:hidden;box-sizing:border-box}li.fancybox-thumbs-loading{background:rgba(0,0,0,.1)}.fancybox-thumbs>ul>li>img{position:absolute;top:0;left:0;min-width:100%;min-height:100%;max-width:none;max-height:none;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fancybox-thumbs>ul>li:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;border-radius:2px;border:4px solid #4ea7f9;z-index:99991;opacity:0;transition:all .2s cubic-bezier(.25,.46,.45,.94)}.fancybox-thumbs>ul>li.fancybox-thumbs-active:before{opacity:1}@media (max-width:800px){.fancybox-thumbs{display:none!important}.fancybox-container--thumbs .fancybox-caption-wrap,.fancybox-container--thumbs .fancybox-controls,.fancybox-container--thumbs .fancybox-slider-wrap{right:0}} -------------------------------------------------------------------------------- /js/client/url-template.js: -------------------------------------------------------------------------------- 1 | /* 2 | UriTemplates Template Processor - Version: @VERSION - Dated: @DATE 3 | (c) marc.portier@gmail.com - 2011-2012 4 | Licensed under APLv2 (http://opensource.org/licenses/Apache-2.0) 5 | */ 6 | 7 | ; 8 | var uritemplate = (function() { 9 | 10 | // Below are the functions we originally used from jQuery. 11 | // The implementations below are often more naive then what is inside jquery, but they suffice for our needs. 12 | 13 | function isFunction(fn) { 14 | return typeof fn == 'function'; 15 | } 16 | 17 | function isEmptyObject (obj) { 18 | for(var name in obj){ 19 | return false; 20 | } 21 | return true; 22 | } 23 | 24 | function extend(base, newprops) { 25 | for (var name in newprops) { 26 | base[name] = newprops[name]; 27 | } 28 | return base; 29 | } 30 | 31 | /** 32 | * Create a runtime cache around retrieved values from the context. 33 | * This allows for dynamic (function) results to be kept the same for multiple 34 | * occuring expansions within one template. 35 | * Note: Uses key-value tupples to be able to cache null values as well. 36 | */ 37 | //TODO move this into prep-processing 38 | function CachingContext(context) { 39 | this.raw = context; 40 | this.cache = {}; 41 | } 42 | CachingContext.prototype.get = function(key) { 43 | var val = this.lookupRaw(key); 44 | var result = val; 45 | 46 | if (isFunction(val)) { // check function-result-cache 47 | var tupple = this.cache[key]; 48 | if (tupple !== null && tupple !== undefined) { 49 | result = tupple.val; 50 | } else { 51 | result = val(this.raw); 52 | this.cache[key] = {key: key, val: result}; 53 | // NOTE: by storing tupples we make sure a null return is validly consistent too in expansions 54 | } 55 | } 56 | return result; 57 | }; 58 | 59 | CachingContext.prototype.lookupRaw = function(key) { 60 | return CachingContext.lookup(this, this.raw, key); 61 | }; 62 | 63 | CachingContext.lookup = function(me, context, key) { 64 | var result = context[key]; 65 | if (result !== undefined) { 66 | return result; 67 | } else { 68 | var keyparts = key.split('.'); 69 | var i = 0, keysplits = keyparts.length - 1; 70 | for (i = 0; i undefined 397 | * typeof document -> undefined 398 | * 399 | * react-native: 400 | * typeof document.createelement -> undefined 401 | */ 402 | function isStandardBrowserEnv() { 403 | return ( 404 | typeof window !== 'undefined' && 405 | typeof document !== 'undefined' && 406 | typeof document.createElement === 'function' 407 | ); 408 | } 409 | 410 | /** 411 | * Iterate over an Array or an Object invoking a function for each item. 412 | * 413 | * If `obj` is an Array or arguments callback will be called passing 414 | * the value, index, and complete array for each item. 415 | * 416 | * If 'obj' is an Object callback will be called passing 417 | * the value, key, and complete object for each property. 418 | * 419 | * @param {Object|Array} obj The object to iterate 420 | * @param {Function} fn The callback to invoke for each item 421 | */ 422 | function forEach(obj, fn) { 423 | // Don't bother if no value provided 424 | if (obj === null || typeof obj === 'undefined') { 425 | return; 426 | } 427 | 428 | // Check if obj is array-like 429 | var isArrayLike = isArray(obj) || isArguments(obj); 430 | 431 | // Force an array if not already something iterable 432 | if (typeof obj !== 'object' && !isArrayLike) { 433 | obj = [obj]; 434 | } 435 | 436 | // Iterate over array values 437 | if (isArrayLike) { 438 | for (var i = 0, l = obj.length; i < l; i++) { 439 | fn.call(null, obj[i], i, obj); 440 | } 441 | } 442 | // Iterate over object keys 443 | else { 444 | for (var key in obj) { 445 | if (obj.hasOwnProperty(key)) { 446 | fn.call(null, obj[key], key, obj); 447 | } 448 | } 449 | } 450 | } 451 | 452 | /** 453 | * Accepts varargs expecting each argument to be an object, then 454 | * immutably merges the properties of each object and returns result. 455 | * 456 | * When multiple objects contain the same key the later object in 457 | * the arguments list will take precedence. 458 | * 459 | * Example: 460 | * 461 | * ```js 462 | * var result = merge({foo: 123}, {foo: 456}); 463 | * console.log(result.foo); // outputs 456 464 | * ``` 465 | * 466 | * @param {Object} obj1 Object to merge 467 | * @returns {Object} Result of all merge properties 468 | */ 469 | function merge(/*obj1, obj2, obj3, ...*/) { 470 | var result = {}; 471 | forEach(arguments, function (obj) { 472 | forEach(obj, function (val, key) { 473 | result[key] = val; 474 | }); 475 | }); 476 | return result; 477 | } 478 | 479 | module.exports = { 480 | isArray: isArray, 481 | isArrayBuffer: isArrayBuffer, 482 | isFormData: isFormData, 483 | isArrayBufferView: isArrayBufferView, 484 | isString: isString, 485 | isNumber: isNumber, 486 | isObject: isObject, 487 | isUndefined: isUndefined, 488 | isDate: isDate, 489 | isFile: isFile, 490 | isBlob: isBlob, 491 | isStandardBrowserEnv: isStandardBrowserEnv, 492 | forEach: forEach, 493 | merge: merge, 494 | trim: trim 495 | }; 496 | 497 | 498 | /***/ }, 499 | /* 4 */ 500 | /***/ function(module, exports, __webpack_require__) { 501 | 502 | /* WEBPACK VAR INJECTION */(function(process) {'use strict'; 503 | 504 | /** 505 | * Dispatch a request to the server using whichever adapter 506 | * is supported by the current environment. 507 | * 508 | * @param {object} config The config that is to be used for the request 509 | * @returns {Promise} The Promise to be fulfilled 510 | */ 511 | module.exports = function dispatchRequest(config) { 512 | return new Promise(function (resolve, reject) { 513 | try { 514 | // For browsers use XHR adapter 515 | if ((typeof XMLHttpRequest !== 'undefined') || (typeof ActiveXObject !== 'undefined')) { 516 | __webpack_require__(6)(resolve, reject, config); 517 | } 518 | // For node use HTTP adapter 519 | else if (typeof process !== 'undefined') { 520 | __webpack_require__(6)(resolve, reject, config); 521 | } 522 | } catch (e) { 523 | reject(e); 524 | } 525 | }); 526 | }; 527 | 528 | 529 | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5))) 530 | 531 | /***/ }, 532 | /* 5 */ 533 | /***/ function(module, exports) { 534 | 535 | // shim for using process in browser 536 | 537 | var process = module.exports = {}; 538 | var queue = []; 539 | var draining = false; 540 | var currentQueue; 541 | var queueIndex = -1; 542 | 543 | function cleanUpNextTick() { 544 | draining = false; 545 | if (currentQueue.length) { 546 | queue = currentQueue.concat(queue); 547 | } else { 548 | queueIndex = -1; 549 | } 550 | if (queue.length) { 551 | drainQueue(); 552 | } 553 | } 554 | 555 | function drainQueue() { 556 | if (draining) { 557 | return; 558 | } 559 | var timeout = setTimeout(cleanUpNextTick); 560 | draining = true; 561 | 562 | var len = queue.length; 563 | while(len) { 564 | currentQueue = queue; 565 | queue = []; 566 | while (++queueIndex < len) { 567 | if (currentQueue) { 568 | currentQueue[queueIndex].run(); 569 | } 570 | } 571 | queueIndex = -1; 572 | len = queue.length; 573 | } 574 | currentQueue = null; 575 | draining = false; 576 | clearTimeout(timeout); 577 | } 578 | 579 | process.nextTick = function (fun) { 580 | var args = new Array(arguments.length - 1); 581 | if (arguments.length > 1) { 582 | for (var i = 1; i < arguments.length; i++) { 583 | args[i - 1] = arguments[i]; 584 | } 585 | } 586 | queue.push(new Item(fun, args)); 587 | if (queue.length === 1 && !draining) { 588 | setTimeout(drainQueue, 0); 589 | } 590 | }; 591 | 592 | // v8 likes predictible objects 593 | function Item(fun, array) { 594 | this.fun = fun; 595 | this.array = array; 596 | } 597 | Item.prototype.run = function () { 598 | this.fun.apply(null, this.array); 599 | }; 600 | process.title = 'browser'; 601 | process.browser = true; 602 | process.env = {}; 603 | process.argv = []; 604 | process.version = ''; // empty string to avoid regexp issues 605 | process.versions = {}; 606 | 607 | function noop() {} 608 | 609 | process.on = noop; 610 | process.addListener = noop; 611 | process.once = noop; 612 | process.off = noop; 613 | process.removeListener = noop; 614 | process.removeAllListeners = noop; 615 | process.emit = noop; 616 | 617 | process.binding = function (name) { 618 | throw new Error('process.binding is not supported'); 619 | }; 620 | 621 | process.cwd = function () { return '/' }; 622 | process.chdir = function (dir) { 623 | throw new Error('process.chdir is not supported'); 624 | }; 625 | process.umask = function() { return 0; }; 626 | 627 | 628 | /***/ }, 629 | /* 6 */ 630 | /***/ function(module, exports, __webpack_require__) { 631 | 632 | 'use strict'; 633 | 634 | /*global ActiveXObject:true*/ 635 | 636 | var defaults = __webpack_require__(2); 637 | var utils = __webpack_require__(3); 638 | var buildUrl = __webpack_require__(7); 639 | var parseHeaders = __webpack_require__(8); 640 | var transformData = __webpack_require__(9); 641 | 642 | module.exports = function xhrAdapter(resolve, reject, config) { 643 | // Transform request data 644 | var data = transformData( 645 | config.data, 646 | config.headers, 647 | config.transformRequest 648 | ); 649 | 650 | // Merge headers 651 | var requestHeaders = utils.merge( 652 | defaults.headers.common, 653 | defaults.headers[config.method] || {}, 654 | config.headers || {} 655 | ); 656 | 657 | if (utils.isFormData(data)) { 658 | // Content-Type needs to be sent in all requests so the mapping template can be applied 659 | //delete requestHeaders['Content-Type']; // Let the browser set it 660 | } 661 | 662 | // Create the request 663 | var request = new (XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP'); 664 | request.open(config.method.toUpperCase(), buildUrl(config.url, config.params), true); 665 | 666 | // Set the request timeout in MS 667 | request.timeout = config.timeout; 668 | 669 | // Listen for ready state 670 | request.onreadystatechange = function () { 671 | if (request && request.readyState === 4) { 672 | // Prepare the response 673 | var responseHeaders = parseHeaders(request.getAllResponseHeaders()); 674 | var responseData = ['text', ''].indexOf(config.responseType || '') !== -1 ? request.responseText : request.response; 675 | var response = { 676 | data: transformData( 677 | responseData, 678 | responseHeaders, 679 | config.transformResponse 680 | ), 681 | status: request.status, 682 | statusText: request.statusText, 683 | headers: responseHeaders, 684 | config: config 685 | }; 686 | 687 | // Resolve or reject the Promise based on the status 688 | (request.status >= 200 && request.status < 300 ? 689 | resolve : 690 | reject)(response); 691 | 692 | // Clean up request 693 | request = null; 694 | } 695 | }; 696 | 697 | // Add xsrf header 698 | // This is only done if running in a standard browser environment. 699 | // Specifically not if we're in a web worker, or react-native. 700 | if (utils.isStandardBrowserEnv()) { 701 | var cookies = __webpack_require__(10); 702 | var urlIsSameOrigin = __webpack_require__(11); 703 | 704 | // Add xsrf header 705 | var xsrfValue = urlIsSameOrigin(config.url) ? 706 | cookies.read(config.xsrfCookieName || defaults.xsrfCookieName) : 707 | undefined; 708 | 709 | if (xsrfValue) { 710 | requestHeaders[config.xsrfHeaderName || defaults.xsrfHeaderName] = xsrfValue; 711 | } 712 | } 713 | 714 | // Add headers to the request 715 | utils.forEach(requestHeaders, function (val, key) { 716 | // Remove Content-Type if data is undefined 717 | if (!data && key.toLowerCase() === 'content-type') { 718 | delete requestHeaders[key]; 719 | } 720 | // Otherwise add header to the request 721 | else { 722 | request.setRequestHeader(key, val); 723 | } 724 | }); 725 | 726 | // Add withCredentials to request if needed 727 | if (config.withCredentials) { 728 | request.withCredentials = true; 729 | } 730 | 731 | // Add responseType to request if needed 732 | if (config.responseType) { 733 | try { 734 | request.responseType = config.responseType; 735 | } catch (e) { 736 | if (request.responseType !== 'json') { 737 | throw e; 738 | } 739 | } 740 | } 741 | 742 | if (utils.isArrayBuffer(data)) { 743 | data = new DataView(data); 744 | } 745 | 746 | // Send the request 747 | request.send(data); 748 | }; 749 | 750 | 751 | /***/ }, 752 | /* 7 */ 753 | /***/ function(module, exports, __webpack_require__) { 754 | 755 | 'use strict'; 756 | 757 | var utils = __webpack_require__(3); 758 | 759 | function encode(val) { 760 | return encodeURIComponent(val). 761 | replace(/%40/gi, '@'). 762 | replace(/%3A/gi, ':'). 763 | replace(/%24/g, '$'). 764 | replace(/%2C/gi, ','). 765 | replace(/%20/g, '+'). 766 | replace(/%5B/gi, '['). 767 | replace(/%5D/gi, ']'); 768 | } 769 | 770 | /** 771 | * Build a URL by appending params to the end 772 | * 773 | * @param {string} url The base of the url (e.g., http://www.google.com) 774 | * @param {object} [params] The params to be appended 775 | * @returns {string} The formatted url 776 | */ 777 | module.exports = function buildUrl(url, params) { 778 | if (!params) { 779 | return url; 780 | } 781 | 782 | var parts = []; 783 | 784 | utils.forEach(params, function (val, key) { 785 | if (val === null || typeof val === 'undefined') { 786 | return; 787 | } 788 | 789 | if (utils.isArray(val)) { 790 | key = key + '[]'; 791 | } 792 | 793 | if (!utils.isArray(val)) { 794 | val = [val]; 795 | } 796 | 797 | utils.forEach(val, function (v) { 798 | if (utils.isDate(v)) { 799 | v = v.toISOString(); 800 | } 801 | else if (utils.isObject(v)) { 802 | v = JSON.stringify(v); 803 | } 804 | parts.push(encode(key) + '=' + encode(v)); 805 | }); 806 | }); 807 | 808 | if (parts.length > 0) { 809 | url += (url.indexOf('?') === -1 ? '?' : '&') + parts.join('&'); 810 | } 811 | 812 | return url; 813 | }; 814 | 815 | 816 | /***/ }, 817 | /* 8 */ 818 | /***/ function(module, exports, __webpack_require__) { 819 | 820 | 'use strict'; 821 | 822 | var utils = __webpack_require__(3); 823 | 824 | /** 825 | * Parse headers into an object 826 | * 827 | * ``` 828 | * Date: Wed, 27 Aug 2014 08:58:49 GMT 829 | * Content-Type: application/json 830 | * Connection: keep-alive 831 | * Transfer-Encoding: chunked 832 | * ``` 833 | * 834 | * @param {String} headers Headers needing to be parsed 835 | * @returns {Object} Headers parsed into an object 836 | */ 837 | module.exports = function parseHeaders(headers) { 838 | var parsed = {}, key, val, i; 839 | 840 | if (!headers) { return parsed; } 841 | 842 | utils.forEach(headers.split('\n'), function(line) { 843 | i = line.indexOf(':'); 844 | key = utils.trim(line.substr(0, i)).toLowerCase(); 845 | val = utils.trim(line.substr(i + 1)); 846 | 847 | if (key) { 848 | parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; 849 | } 850 | }); 851 | 852 | return parsed; 853 | }; 854 | 855 | 856 | /***/ }, 857 | /* 9 */ 858 | /***/ function(module, exports, __webpack_require__) { 859 | 860 | 'use strict'; 861 | 862 | var utils = __webpack_require__(3); 863 | 864 | /** 865 | * Transform the data for a request or a response 866 | * 867 | * @param {Object|String} data The data to be transformed 868 | * @param {Array} headers The headers for the request or response 869 | * @param {Array|Function} fns A single function or Array of functions 870 | * @returns {*} The resulting transformed data 871 | */ 872 | module.exports = function transformData(data, headers, fns) { 873 | utils.forEach(fns, function (fn) { 874 | data = fn(data, headers); 875 | }); 876 | 877 | return data; 878 | }; 879 | 880 | 881 | /***/ }, 882 | /* 10 */ 883 | /***/ function(module, exports, __webpack_require__) { 884 | 885 | 'use strict'; 886 | 887 | /** 888 | * WARNING: 889 | * This file makes references to objects that aren't safe in all environments. 890 | * Please see lib/utils.isStandardBrowserEnv before including this file. 891 | */ 892 | 893 | var utils = __webpack_require__(3); 894 | 895 | module.exports = { 896 | write: function write(name, value, expires, path, domain, secure) { 897 | var cookie = []; 898 | cookie.push(name + '=' + encodeURIComponent(value)); 899 | 900 | if (utils.isNumber(expires)) { 901 | cookie.push('expires=' + new Date(expires).toGMTString()); 902 | } 903 | 904 | if (utils.isString(path)) { 905 | cookie.push('path=' + path); 906 | } 907 | 908 | if (utils.isString(domain)) { 909 | cookie.push('domain=' + domain); 910 | } 911 | 912 | if (secure === true) { 913 | cookie.push('secure'); 914 | } 915 | 916 | document.cookie = cookie.join('; '); 917 | }, 918 | 919 | read: function read(name) { 920 | var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); 921 | return (match ? decodeURIComponent(match[3]) : null); 922 | }, 923 | 924 | remove: function remove(name) { 925 | this.write(name, '', Date.now() - 86400000); 926 | } 927 | }; 928 | 929 | 930 | /***/ }, 931 | /* 11 */ 932 | /***/ function(module, exports, __webpack_require__) { 933 | 934 | 'use strict'; 935 | 936 | /** 937 | * WARNING: 938 | * This file makes references to objects that aren't safe in all environments. 939 | * Please see lib/utils.isStandardBrowserEnv before including this file. 940 | */ 941 | 942 | var utils = __webpack_require__(3); 943 | var msie = /(msie|trident)/i.test(navigator.userAgent); 944 | var urlParsingNode = document.createElement('a'); 945 | var originUrl; 946 | 947 | /** 948 | * Parse a URL to discover it's components 949 | * 950 | * @param {String} url The URL to be parsed 951 | * @returns {Object} 952 | */ 953 | function urlResolve(url) { 954 | var href = url; 955 | 956 | if (msie) { 957 | // IE needs attribute set twice to normalize properties 958 | urlParsingNode.setAttribute('href', href); 959 | href = urlParsingNode.href; 960 | } 961 | 962 | urlParsingNode.setAttribute('href', href); 963 | 964 | // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils 965 | return { 966 | href: urlParsingNode.href, 967 | protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', 968 | host: urlParsingNode.host, 969 | search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', 970 | hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', 971 | hostname: urlParsingNode.hostname, 972 | port: urlParsingNode.port, 973 | pathname: (urlParsingNode.pathname.charAt(0) === '/') ? 974 | urlParsingNode.pathname : 975 | '/' + urlParsingNode.pathname 976 | }; 977 | } 978 | 979 | originUrl = urlResolve(window.location.href); 980 | 981 | /** 982 | * Determine if a URL shares the same origin as the current location 983 | * 984 | * @param {String} requestUrl The URL to test 985 | * @returns {boolean} True if URL shares the same origin, otherwise false 986 | */ 987 | module.exports = function urlIsSameOrigin(requestUrl) { 988 | var parsed = (utils.isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl; 989 | return (parsed.protocol === originUrl.protocol && 990 | parsed.host === originUrl.host); 991 | }; 992 | 993 | 994 | /***/ }, 995 | /* 12 */ 996 | /***/ function(module, exports, __webpack_require__) { 997 | 998 | 'use strict'; 999 | 1000 | var utils = __webpack_require__(3); 1001 | 1002 | function InterceptorManager() { 1003 | this.handlers = []; 1004 | } 1005 | 1006 | /** 1007 | * Add a new interceptor to the stack 1008 | * 1009 | * @param {Function} fulfilled The function to handle `then` for a `Promise` 1010 | * @param {Function} rejected The function to handle `reject` for a `Promise` 1011 | * 1012 | * @return {Number} An ID used to remove interceptor later 1013 | */ 1014 | InterceptorManager.prototype.use = function (fulfilled, rejected) { 1015 | this.handlers.push({ 1016 | fulfilled: fulfilled, 1017 | rejected: rejected 1018 | }); 1019 | return this.handlers.length - 1; 1020 | }; 1021 | 1022 | /** 1023 | * Remove an interceptor from the stack 1024 | * 1025 | * @param {Number} id The ID that was returned by `use` 1026 | */ 1027 | InterceptorManager.prototype.eject = function (id) { 1028 | if (this.handlers[id]) { 1029 | this.handlers[id] = null; 1030 | } 1031 | }; 1032 | 1033 | /** 1034 | * Iterate over all the registered interceptors 1035 | * 1036 | * This method is particularly useful for skipping over any 1037 | * interceptors that may have become `null` calling `remove`. 1038 | * 1039 | * @param {Function} fn The function to call for each interceptor 1040 | */ 1041 | InterceptorManager.prototype.forEach = function (fn) { 1042 | utils.forEach(this.handlers, function (h) { 1043 | if (h !== null) { 1044 | fn(h); 1045 | } 1046 | }); 1047 | }; 1048 | 1049 | module.exports = InterceptorManager; 1050 | 1051 | 1052 | /***/ }, 1053 | /* 13 */ 1054 | /***/ function(module, exports) { 1055 | 1056 | 'use strict'; 1057 | 1058 | /** 1059 | * Syntactic sugar for invoking a function and expanding an array for arguments. 1060 | * 1061 | * Common use case would be to use `Function.prototype.apply`. 1062 | * 1063 | * ```js 1064 | * function f(x, y, z) {} 1065 | * var args = [1, 2, 3]; 1066 | * f.apply(null, args); 1067 | * ``` 1068 | * 1069 | * With `spread` this example can be re-written. 1070 | * 1071 | * ```js 1072 | * spread(function(x, y, z) {})([1, 2, 3]); 1073 | * ``` 1074 | * 1075 | * @param {Function} callback 1076 | * @returns {Function} 1077 | */ 1078 | module.exports = function spread(callback) { 1079 | return function (arr) { 1080 | return callback.apply(null, arr); 1081 | }; 1082 | }; 1083 | 1084 | 1085 | /***/ } 1086 | /******/ ]) 1087 | }); 1088 | ; 1089 | //# sourceMappingURL=axios.map -------------------------------------------------------------------------------- /js/fancybox.js: -------------------------------------------------------------------------------- 1 | // ================================================== 2 | // fancyBox v3.0.29 3 | // 4 | // Licensed GPLv3 for open source use 5 | // or fancyBox Commercial License for commercial use 6 | // 7 | // http://fancyapps.com/fancybox/ 8 | // Copyright 2017 fancyApps 9 | // 10 | // ================================================== 11 | !function(t,e,n,o){"use strict";function s(t){var e=t.currentTarget,o=t.data?t.data.options:{},s=t.data?t.data.items:[],i="",a=0;t.preventDefault(),t.stopPropagation(),n(e).attr("data-fancybox")&&(i=n(e).data("fancybox")),i?(s=s.length?s.filter('[data-fancybox="'+i+'"]'):n("[data-fancybox="+i+"]"),a=s.index(e)):s=[e],n.fancybox.open(s,o,a)}if(!n)return o;var i={speed:330,loop:!0,opacity:"auto",margin:[44,0],gutter:30,infobar:!0,buttons:!0,slideShow:!0,fullScreen:!0,thumbs:!0,closeBtn:!0,smallBtn:"auto",image:{preload:"auto",protect:!1},ajax:{settings:{data:{fancybox:!0}}},iframe:{tpl:'',preload:!0,scrolling:"no",css:{}},baseClass:"",slideClass:"",baseTpl:'',spinnerTpl:'
    ',errorTpl:'

    The requested content cannot be loaded.
    Please try again later.

    ',closeTpl:'',parentEl:"body",touch:!0,keyboard:!0,focus:!0,closeClickOutside:!0,beforeLoad:n.noop,afterLoad:n.noop,beforeMove:n.noop,afterMove:n.noop,onComplete:n.noop,onInit:n.noop,beforeClose:n.noop,afterClose:n.noop,onActivate:n.noop,onDeactivate:n.noop},a=n(t),r=n(e),c=0,l=function(t){return t&&t.hasOwnProperty&&t instanceof n},u=function(){return t.requestAnimationFrame||t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||function(e){t.setTimeout(e,1e3/60)}}(),d=function(o){var s;return"function"==typeof n&&o instanceof n&&(o=o[0]),s=o.getBoundingClientRect(),s.bottom>0&&s.right>0&&s.left<(t.innerWidth||e.documentElement.clientWidth)&&s.top<(t.innerHeight||e.documentElement.clientHeight)},p=function(t,o,s){var a=this;a.opts=n.extend(!0,{index:s},i,o||{}),a.id=a.opts.id||++c,a.group=[],a.currIndex=parseInt(a.opts.index,10)||0,a.prevIndex=null,a.prevPos=null,a.currPos=0,a.firstRun=null,a.createGroup(t),a.group.length&&(a.$lastFocus=n(e.activeElement),a.elems={},a.slides={},a.init(t))};n.extend(p.prototype,{init:function(){var t,e,o=this;o.scrollTop=a.scrollTop(),o.scrollLeft=a.scrollLeft(),n.fancybox.isTouch||n("html").hasClass("fancybox-enabled")||(t=n("body").width(),n("html").addClass("fancybox-enabled"),t=n("body").width()-t,t>1&&n('