{
  "info": {
    "_postman_id": "e22486fb-006b-443d-b420-27d0d9947499",
    "name": "Fluent CLI B2C Sample Collection",
    "description": "_Fluent CLI B2C Test Collection - © 2024 Fluent Commerce. All Rights Reserved._\n\n### Legal Notice\n\n> _Copyright © 2024 Fluent Commerce - All Rights Reserved._ \n  \n\n---",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "_exporter_id": "54866073"
  },
  "item": [
    {
      "name": "Account",
      "item": [
        {
          "name": "Authenticate Account Users",
          "item": [
            {
              "name": "Fluent Auth - Account Admin User",
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "// const env_manager = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.env_manager\"));",
                      "",
                      "const jsonData = pm.response.json();",
                      "",
                      "// env_manager.setTokenVars(\"fluent.account\", jsonData);",
                      "// env_manager.setCurrentAccountUser(\"fluent.account\");",
                      "",
                      "pm.environment.set(\"fluent.account.token\", jsonData.access_token);",
                      "",
                      "var expiryTime = new Date(Date.now() + (jsonData.expires_in * 1000));",
                      "console.log(\"Token will expire at: \" + expiryTime);",
                      "pm.environment.set(\"fluent.account.token.expiry_time\", expiryTime);",
                      "",
                      "",
                      "pm.environment.set(\"fluent.account.current.user.username\", pm.environment.get(\"fluent.account.username\"));",
                      "pm.environment.set(\"fluent.account.current.user.password\", pm.environment.get(\"fluent.account.password\"));",
                      "//pm.environment.set(\"fluent.account.current.user.id\", );",
                      "//pm.environment.set(\"fluent.account.current.user.ref\", );",
                      "pm.environment.set(\"fluent.account.current.token\", jsonData.access_token);",
                      "pm.environment.set(\"fluent.account.current.token.expiry_time\", expiryTime);",
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {}
                  }
                },
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {}
                  }
                }
              ],
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "header": [],
                "url": {
                  "raw": "{{fluent.account.host}}/oauth/token?username={{fluent.account.username}}&password={{fluent.account.password}}&client_id={{fluent.account.client_id}}&client_secret={{fluent.account.client_secret}}&scope=api&grant_type=password",
                  "host": [
                    "{{fluent.account.host}}"
                  ],
                  "path": [
                    "oauth",
                    "token"
                  ],
                  "query": [
                    {
                      "key": "username",
                      "value": "{{fluent.account.username}}",
                      "description": "Fluent Account Super User Username"
                    },
                    {
                      "key": "password",
                      "value": "{{fluent.account.password}}",
                      "description": "Fluent Account Super User Password"
                    },
                    {
                      "key": "client_id",
                      "value": "{{fluent.account.client_id}}",
                      "description": "Fluent Account Id / Client Id"
                    },
                    {
                      "key": "client_secret",
                      "value": "{{fluent.account.client_secret}}",
                      "description": "Fluent Account Client Secret"
                    },
                    {
                      "key": "scope",
                      "value": "api"
                    },
                    {
                      "key": "grant_type",
                      "value": "password"
                    }
                  ]
                },
                "description": "## Authenticate the Account Admin User\n\nUse this request to Authenticate your Default Account Admin User.\n\nThe response `access_token` will be saved into the `fluent.account.token` and the `fluent.account.current.token` environment variables for use in future requests.\n\nFor more information: [Fluent API Authentication](https://lingo.fluentcommerce.com/DEVELOPERS/authentication/)"
              },
              "response": [
                {
                  "name": "Fluent Auth - Account: SUCCESS",
                  "originalRequest": {
                    "method": "POST",
                    "header": [],
                    "url": {
                      "raw": "{{fluent.account.host}}/oauth/token?username={{fluent.account.username}}&password={{fluent.account.password}}&client_id={{fluent.account.client_id}}&client_secret={{fluent.account.client_secret}}&scope=api&grant_type=password",
                      "host": [
                        "{{fluent.account.host}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ],
                      "query": [
                        {
                          "key": "username",
                          "value": "{{fluent.account.username}}",
                          "description": "Fluent Account Admin User Username"
                        },
                        {
                          "key": "password",
                          "value": "{{fluent.account.password}}",
                          "description": "Fluent Account Admin User Password"
                        },
                        {
                          "key": "client_id",
                          "value": "{{fluent.account.client_id}}",
                          "description": "Fluent Account Id / Client Id"
                        },
                        {
                          "key": "client_secret",
                          "value": "{{fluent.account.client_secret}}",
                          "description": "Fluent Account Client Secret"
                        },
                        {
                          "key": "scope",
                          "value": "api"
                        },
                        {
                          "key": "grant_type",
                          "value": "password"
                        }
                      ]
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Date",
                      "value": "Tue, 29 Oct 2019 00:45:57 GMT"
                    },
                    {
                      "key": "Content-Type",
                      "value": "application/json;charset=UTF-8"
                    },
                    {
                      "key": "Transfer-Encoding",
                      "value": "chunked"
                    },
                    {
                      "key": "Connection",
                      "value": "keep-alive"
                    },
                    {
                      "key": "Server",
                      "value": "nginx/1.10.3 (Ubuntu)"
                    },
                    {
                      "key": "Access-Control-Allow-Origin",
                      "value": "*"
                    },
                    {
                      "key": "Access-Control-Allow-Methods",
                      "value": "POST, PUT, GET, OPTIONS, DELETE"
                    },
                    {
                      "key": "Access-Control-Max-Age",
                      "value": "3600"
                    },
                    {
                      "key": "Access-Control-Allow-Headers",
                      "value": "Authorization, Content-Type, fluent.account"
                    },
                    {
                      "key": "Access-Control-Expose-Headers",
                      "value": "flex.type, flex.version"
                    },
                    {
                      "key": "Access-Control-Allow-Credentials",
                      "value": "true"
                    },
                    {
                      "key": "X-Content-Type-Options",
                      "value": "nosniff"
                    },
                    {
                      "key": "X-XSS-Protection",
                      "value": "1; mode=block"
                    },
                    {
                      "key": "Cache-Control",
                      "value": "no-cache, no-store, max-age=0, must-revalidate"
                    },
                    {
                      "key": "Cache-Control",
                      "value": "no-store"
                    },
                    {
                      "key": "Pragma",
                      "value": "no-cache"
                    },
                    {
                      "key": "Pragma",
                      "value": "no-cache"
                    },
                    {
                      "key": "Expires",
                      "value": "0"
                    },
                    {
                      "key": "X-Frame-Options",
                      "value": "DENY"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n    \"access_token\": \"4b5eb7aa-5714-4c73-8813-4e4aae0a3e0f\",\n    \"token_type\": \"bearer\",\n    \"expires_in\": 2579,\n    \"scope\": \"api\",\n    \"Roles\": [],\n    \"FirstName\": \"Bob\",\n    \"LastName\": \"Smith\"\n}"
                }
              ]
            },
            {
              "name": "Get Current Account User Me",
              "request": {
                "auth": {
                  "type": "bearer",
                  "bearer": [
                    {
                      "key": "token",
                      "value": "{{fluent.account.token}}",
                      "type": "string"
                    }
                  ]
                },
                "method": "POST",
                "header": [],
                "body": {
                  "mode": "graphql",
                  "graphql": {
                    "query": "query getCurrentAccountUserMe {\n    me {\n        id\n        ref\n        type\n        status\n        username\n        createdOn\n        updatedOn\n        title\n        firstName\n        lastName\n        primaryEmail\n        primaryPhone\n        department\n        country\n        timezone\n        language {\n            label\n            value\n        }\n        attributes {\n            name\n            type\n            value\n        }\n        promotionOptIn\n        primaryRetailer {\n            id\n            ref\n            tradingName\n            status\n        }\n        primaryLocation {\n            id\n            ref\n            type\n            status\n            name\n        }\n        roles {\n            role {\n                name\n                # permissions {\n                #     name\n                # }\n            }\n            contexts {\n                contextType\n                contextId\n            }\n        }\n    }\n}",
                    "variables": ""
                  }
                },
                "url": {
                  "raw": "{{fluent.account.host}}/graphql",
                  "host": [
                    "{{fluent.account.host}}"
                  ],
                  "path": [
                    "graphql"
                  ]
                },
                "description": "Returns information about the currently authenticated user."
              },
              "response": []
            }
          ],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  ""
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  ""
                ]
              }
            }
          ]
        },
        {
          "name": "Get Plugin Rules",
          "item": [
            {
              "name": "Get Account Rules",
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const utils = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.utils\"));",
                      "const visualiser_utils = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.visualiser_utils\"));",
                      "const visualiser_templates = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.visualiser_templates\"));",
                      "",
                      "const jsonData = pm.response.json();",
                      "",
                      "let plugins = [];",
                      "",
                      "//for (var key of Object.keys(jsonData)) {",
                      "",
                      "Object.keys(jsonData).forEach(function(key, index) {",
                      "",
                      "    let plugin = {};",
                      "",
                      "    // console.log(`Plugin Count: ${plugins.length}`);",
                      "    // if (index < 5) {",
                      "    //     console.log(`Plugins: ${JSON.stringify(plugins)}`);",
                      "    // }",
                      "",
                      "",
                      "    // let r = jsonData[index];",
                      "    let r = jsonData[key];",
                      "    let lastDot = key.lastIndexOf(\".\");",
                      "    let ns = key.substring(0,lastDot);",
                      "",
                      "    // console.log(`r: ${JSON.stringify(r)}`);",
                      "",
                      "    // console.log(`Namespace: ${ns} == plugins[index].namespace: ${plugins[index].namespace}`);",
                      "",
                      "    // console.log(`Namespace: ${ns}, ${key}`);",
                      "    let existing = plugins.findIndex(p => p.namespace === ns);",
                      "    // console.log(`Index: ${index}, Namespace: ${ns}, key: ${key}, existing: ${existing}`);",
                      "    if (existing > -1) {",
                      "        plugin = plugins[existing];",
                      "        // console.log(`Found plugin: ${plugin.namespace}, rule count: ${plugin.rules.length}`);",
                      "    } else {",
                      "        plugin.namespace = ns;",
                      "        plugin.rules = [];",
                      "    }",
                      "",
                      "    let rule = {};",
                      "    rule.name = r.name;",
                      "    rule.description = r.description;",
                      "    // rule.accepts = JSON.stringify(r.ruleInfo.accepts, null, 1);",
                      "    // rule.produces = JSON.stringify(r.ruleInfo.produces, null, 1);",
                      "    // rule.exceptions = JSON.stringify(r.ruleInfo.ruleException, null, 1);",
                      "    rule.accepts = r.ruleInfo.accepts;",
                      "    rule.produces = r.ruleInfo.produces;",
                      "    rule.exceptions = r.ruleInfo.ruleException;",
                      "    rule.parameters = [];",
                      "    rule.attributes = [];",
                      "",
                      "    let param = {};",
                      "    for (p in r.parameters) {",
                      "        param = r.parameters[p];",
                      "        rule.parameters.push(param);",
                      "    }",
                      "",
                      "    let attribute = {};",
                      "    for (a in r.eventAttributes) {",
                      "        attribute = r.eventAttributes[a];",
                      "        rule.attributes.push(attribute);",
                      "    }",
                      "",
                      "    plugin.rules.push(rule);",
                      "",
                      "    if (existing > -1) {",
                      "        plugins[existing] = plugin;",
                      "        // console.log(`${index} Updated existing plugin, namespace: '${plugin.namespace}' === '${ns}', rule count: ${plugin.rules.length}`);",
                      "    } else {",
                      "        plugins.push(plugin);",
                      "        console.log(`${index} Added new plugin, namespace: '${plugin.namespace}' === '${ns}', rule count: ${plugin.rules.length}`);",
                      "        // if (index === 0) {",
                      "            // console.log(`First Plugin: ${JSON.stringify(plugin)}`);",
                      "        // }",
                      "    }",
                      "",
                      "});    ",
                      "",
                      "",
                      "//}",
                      "console.log(`Plugin Count: ${plugins.length}`);",
                      "// console.log(`Lesley Plugin: ${JSON.stringify(plugins.find(p => p.namespace == \"FCTRAINAU31.lesley\"))}`);",
                      "// for (p in plugins) {",
                      "//     console.log(`Plugin: ${plugins[p].namespace}, rule count: ${plugins[p].rules.length}`);",
                      "//     // console.log(`Plugin: ${p.namespace}`);",
                      "// }",
                      "",
                      "plugins.sort((a,b) => {return (a.namespace < b.namespace) ? -1 : (a.namespace > b.namespace) ? 1 : 0});",
                      "",
                      "// for (p in plugins) {",
                      "//     console.log(`Sorted Plugin: ${plugins[p].namespace}, rule count: ${plugins[p].rules.length}`);",
                      "//     // console.log(`Plugin: ${p.namespace}`);",
                      "// }",
                      "",
                      "let basicTemplate = visualiser_templates.basicTemplate();",
                      "",
                      "let report_data = basicTemplate.data;",
                      "report_data.report.title = `Account Plugins Overview`;",
                      "report_data.report.subTitle = \"Overview of Active Account Plugins: \" + pm.environment.get(\"fluent.account.client_id\");;",
                      "report_data.report.timestamp = new Date().toString();",
                      "report_data.report.columns = [];",
                      "",
                      "report_data.report.head = visualiser_utils.findInPageStylesheet() + visualiser_utils.printScripts();",
                      "",
                      "report_data.report.bodyScripts = visualiser_utils.findInPageScripts() + visualiser_utils.backToTopButton();",
                      "",
                      "// report_data.report.extraHeaderInfo = visualiser_utils.findInPageForm() + visualiser_utils.printButton(\"fluent-content\");",
                      "",
                      "report_data.report.topBar = `<div class=\"level-left\"><div class=\"level-item\">${visualiser_utils.findInPageForm()}</div></div><div class=\"level-right\"><div class=\"level-item\">${visualiser_utils.printButton(\"fluent-content\")}</div></div>`;",
                      "",
                      "",
                      "let overview = [];",
                      "",
                      "plugins.forEach(function(key, index) {",
                      "",
                      "    let plugin = plugins[index];",
                      "    let anchor = getPluginAnchorName(plugin.namespace);",
                      "",
                      "    let overviewItem = {};",
                      "    overviewItem.pluginName = `<a href=\"#${anchor}\">${plugin.namespace}</a>`;",
                      "    overviewItem.ruleCount = plugin.rules.length;",
                      "    overview.push(overviewItem);",
                      "",
                      "});",
                      "",
                      "let table = visualiser_utils.json2table(overview, \"table is-fullwidth is-striped is-size-7\");",
                      "let col = {title: \"Plugin Overview\", content: table};",
                      "report_data.report.columns.push(col);",
                      "",
                      "",
                      "plugins.forEach(function(key, index) {",
                      "",
                      "    let plugin = plugins[index];",
                      "    ",
                      "    plugin.rules.sort((a,b) => {return (a.name < b.name) ? -1 : (a.name > b.name) ? 1 : 0});",
                      "",
                      "    let rows = [];",
                      "    plugin.rules.forEach(function(key, index) {",
                      "        let r = plugin.rules[index];",
                      "",
                      "        let row = {};",
                      "        row.rule = `<strong>${r.name}</strong><br/>${r.description}`;",
                      "        row.accepts = \"\";",
                      "        r.accepts.forEach(a => {",
                      "            row.accepts += `${a.entityType}<br/>`;",
                      "        });",
                      "        row.parameters = \"\";",
                      "        r.parameters.forEach(p => {",
                      "            row.parameters += `<strong>${p.name}</strong> <em>${p.type}</em><br/>${p.description}<br/>`;",
                      "        });",
                      "        row.attributes = \"\";",
                      "        r.attributes.forEach(a => {",
                      "            row.attributes += `<strong>${a.name}</strong> <em>${a.type}</em><br/>`;",
                      "        });",
                      "        row.produces = \"\";",
                      "        r.produces.forEach(p => {",
                      "            row.produces += `<strong>Event Name:</strong> ${p.eventName}<br/><strong>Entity Type:</strong> ${p.entityType}<br/><strong>Entity Subtype:</strong> ${p.entitySubtype}<br/><strong>Entity Status:</strong> ${p.status}<br/><br/>`;",
                      "        });",
                      "        rows.push(row);",
                      "    });",
                      "",
                      "    // let table = visualiser_utils.json2table(plugin.rules, \"table is-fullwidth is-striped is-size-7\");",
                      "    let table = visualiser_utils.json2table(rows, \"table is-fullwidth is-striped is-size-7\");",
                      "",
                      "    let anchor = getPluginAnchorName(plugin.namespace);",
                      "",
                      "    let col = {title: plugin.namespace, anchor: anchor, content: table};",
                      "    report_data.report.columns.push(col);",
                      "});",
                      "pm.visualizer.set(basicTemplate.template, report_data);",
                      "",
                      "",
                      "function getPluginAnchorName(namespace) {",
                      "    let parts = namespace.split(\".\");",
                      "    return `${parts[0].toLowerCase()}-${parts[1]}`;",
                      "}",
                      "",
                      "// let retailer_table = visualiser_utils.json2table(jsonData.data.Retailers.edges, \"table is-fullwidth is-striped\");",
                      "// let user_table = visualiser_utils.json2table(jsonData.data.AccountUsers.edges, \"table is-fullwidth is-striped\");",
                      "// let setting_table = visualiser_utils.json2table(jsonData.data.AccountSettings.edges, \"table is-fullwidth is-striped\");",
                      "",
                      "// let col1 = {title: \"Retailers\", content: retailer_table};",
                      "// let col2 = {title: \"Account Users\", content: user_table};",
                      "// let col3 = {title: \"Account Settings\", content: setting_table};",
                      "",
                      "// report_data.report.columns[0] = col1;",
                      "// report_data.report.columns.push(col2);",
                      "// report_data.report.columns.push(col3);",
                      "",
                      "",
                      "",
                      "// console.log(`All Plugins: ${JSON.stringify(plugins)}`);",
                      "",
                      "// // // TODO: Visualise",
                      "",
                      "",
                      "/*",
                      "let plugin = {",
                      "    namespace: \"\",",
                      "    rules: []",
                      "};",
                      "",
                      "let rule = {",
                      "    name: \"\",",
                      "    description: \"\",",
                      "    accepts: \"\",",
                      "    produces: \"\",",
                      "    exceptions: \"\",",
                      "    parameters: [],",
                      "    attributes: [],",
                      "    exceptions: []",
                      "};",
                      "",
                      "let param = {",
                      "    name: \"\",",
                      "    type: \"\",",
                      "    description: \"\",",
                      "    multiple: \"\"",
                      "};",
                      "",
                      "let attribute = {",
                      "    name: \"\",",
                      "    type: \"\"",
                      "};",
                      "",
                      "",
                      "*/",
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {}
                  }
                }
              ],
              "request": {
                "auth": {
                  "type": "bearer",
                  "bearer": [
                    {
                      "key": "token",
                      "value": "{{fluent.account.token}}",
                      "type": "string"
                    }
                  ]
                },
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{fluent.account.host}}/orchestration/rest/v1/plugin/",
                  "host": [
                    "{{fluent.account.host}}"
                  ],
                  "path": [
                    "orchestration",
                    "rest",
                    "v1",
                    "plugin",
                    ""
                  ]
                },
                "description": "This request retrieves all the Rules available on the Account. This is helpful to confirm that the Custom Plugin Rules are available to the Account."
              },
              "response": []
            }
          ]
        }
      ]
    },
    {
      "name": "Retailer",
      "item": [
        {
          "name": "Authenticate Retailer",
          "item": [
            {
              "name": "Fluent Auth - Retailer B2C",
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const jsonData = pm.response.json();",
                      "var currentRetailerRef = pm.environment.get(\"fluent.retailer.current.ref\");",
                      "",
                      "pm.environment.set(\"fluent.retailer.current.token\", jsonData.access_token);",
                      "pm.environment.set(\"fluent.retailer.\" + currentRetailerRef + \".token\", jsonData.access_token);",
                      "",
                      "var expiryTime = new Date(Date.now() + (jsonData.expires_in * 1000));",
                      "console.log(\"Token will expire at: \" + expiryTime);",
                      "pm.environment.set(\"fluent.retailer.current.token.expiry_time\", expiryTime);",
                      "pm.environment.set(\"fluent.retailer.\" + currentRetailerRef + \".token.expiry_time\", expiryTime);",
                      "pm.environment.set(\"fluent.retailer.current.customer.id\", pm.environment.get(\"fluent.retailer.\" + currentRetailerRef + \".customer.id\"));",
                      "",
                      "console.log(\"Setting current retailer token: \" + pm.environment.get(\"fluent.retailer.current.token\") + \", RetailerRef: \" + pm.environment.get(\"fluent.retailer.current.ref\") + \", RetailerId: \" + pm.environment.get(\"fluent.retailer.current.id\"));",
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {}
                  }
                },
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "",
                      "let use_unique_suffix = (pm.environment.has(\"fluent.data.use_unique_suffix\") && pm.environment.get(\"fluent.data.use_unique_suffix\") == true) ? true : false;",
                      "",
                      "let currentRetailerRef = \"b2c\";",
                      "if (use_unique_suffix) {",
                      "    currentRetailerRef = currentRetailerRef + \"_\" + pm.environment.get(\"fluent.data.unique_suffix\");",
                      "}",
                      "",
                      "pm.variables.set(\"b2c_username\", pm.environment.get(\"fluent.retailer.\" + currentRetailerRef + \".user.username\"));",
                      "pm.variables.set(\"b2c_password\", pm.environment.get(\"fluent.retailer.\" + currentRetailerRef + \".user.password\"));",
                      "",
                      "pm.environment.set(\"fluent.retailer.current.id\", pm.environment.get(\"fluent.retailer.\" + currentRetailerRef + \".id\"));",
                      "pm.environment.set(\"fluent.retailer.current.ref\", pm.environment.get(\"fluent.retailer.\" + currentRetailerRef + \".ref\"));",
                      "pm.environment.set(\"fluent.retailer.current.user.username\", pm.environment.get(\"fluent.retailer.\" + currentRetailerRef + \".user.username\"));",
                      "pm.environment.set(\"fluent.retailer.current.user.password\", pm.environment.get(\"fluent.retailer.\" + currentRetailerRef + \".user.password\"));",
                      "",
                      "",
                      "",
                      "console.log(\"Setting Current Retailer: \" + pm.environment.get(\"fluent.retailer.current.ref\") + \", Id: \" + pm.environment.get(\"fluent.retailer.current.id\"));",
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {}
                  }
                }
              ],
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "header": [],
                "url": {
                  "raw": "{{fluent.account.host}}/oauth/token?username={{b2c_username}}&password={{b2c_password}}&client_id={{fluent.account.client_id}}&client_secret={{fluent.account.client_secret}}&scope=api&grant_type=password",
                  "host": [
                    "{{fluent.account.host}}"
                  ],
                  "path": [
                    "oauth",
                    "token"
                  ],
                  "query": [
                    {
                      "key": "username",
                      "value": "{{b2c_username}}",
                      "description": "FC Fashion Admin User Username"
                    },
                    {
                      "key": "password",
                      "value": "{{b2c_password}}",
                      "description": "FC Fashion Admin User Password"
                    },
                    {
                      "key": "client_id",
                      "value": "{{fluent.account.client_id}}",
                      "description": "Fluent Account Id / Client Id"
                    },
                    {
                      "key": "client_secret",
                      "value": "{{fluent.account.client_secret}}",
                      "description": "Fluent Account Client Secret"
                    },
                    {
                      "key": "scope",
                      "value": "api"
                    },
                    {
                      "key": "grant_type",
                      "value": "password"
                    }
                  ]
                },
                "description": "## Authenticate the FC FASHION Retailer Admin User\n\nUse this request to Authenticate your FC FASHION Retailer Admin User.\n\nThe response `access_token` will be saved into the `fluent.retailer.current.token` and the `fluent.retailer.<retailer_ref>.token` environment variable for use in future requests.\n\nFor more information: [Fluent API Authentication](https://lingo.fluentcommerce.com/DEVELOPERS/authentication/)"
              },
              "response": [
                {
                  "name": "Fluent Auth - Account: SUCCESS",
                  "originalRequest": {
                    "method": "POST",
                    "header": [],
                    "url": {
                      "raw": "{{fluent.account.host}}/oauth/token?username={{fluent.account.username}}&password={{fluent.account.password}}&client_id={{fluent.account.client_id}}&client_secret={{fluent.account.client_secret}}&scope=api&grant_type=password",
                      "host": [
                        "{{fluent.account.host}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ],
                      "query": [
                        {
                          "key": "username",
                          "value": "{{fluent.account.username}}",
                          "description": "Fluent Account Admin User Username"
                        },
                        {
                          "key": "password",
                          "value": "{{fluent.account.password}}",
                          "description": "Fluent Account Admin User Password"
                        },
                        {
                          "key": "client_id",
                          "value": "{{fluent.account.client_id}}",
                          "description": "Fluent Account Id / Client Id"
                        },
                        {
                          "key": "client_secret",
                          "value": "{{fluent.account.client_secret}}",
                          "description": "Fluent Account Client Secret"
                        },
                        {
                          "key": "scope",
                          "value": "api"
                        },
                        {
                          "key": "grant_type",
                          "value": "password"
                        }
                      ]
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Date",
                      "value": "Tue, 29 Oct 2019 00:45:57 GMT"
                    },
                    {
                      "key": "Content-Type",
                      "value": "application/json;charset=UTF-8"
                    },
                    {
                      "key": "Transfer-Encoding",
                      "value": "chunked"
                    },
                    {
                      "key": "Connection",
                      "value": "keep-alive"
                    },
                    {
                      "key": "Server",
                      "value": "nginx/1.10.3 (Ubuntu)"
                    },
                    {
                      "key": "Access-Control-Allow-Origin",
                      "value": "*"
                    },
                    {
                      "key": "Access-Control-Allow-Methods",
                      "value": "POST, PUT, GET, OPTIONS, DELETE"
                    },
                    {
                      "key": "Access-Control-Max-Age",
                      "value": "3600"
                    },
                    {
                      "key": "Access-Control-Allow-Headers",
                      "value": "Authorization, Content-Type, fluent.account"
                    },
                    {
                      "key": "Access-Control-Expose-Headers",
                      "value": "flex.type, flex.version"
                    },
                    {
                      "key": "Access-Control-Allow-Credentials",
                      "value": "true"
                    },
                    {
                      "key": "X-Content-Type-Options",
                      "value": "nosniff"
                    },
                    {
                      "key": "X-XSS-Protection",
                      "value": "1; mode=block"
                    },
                    {
                      "key": "Cache-Control",
                      "value": "no-cache, no-store, max-age=0, must-revalidate"
                    },
                    {
                      "key": "Cache-Control",
                      "value": "no-store"
                    },
                    {
                      "key": "Pragma",
                      "value": "no-cache"
                    },
                    {
                      "key": "Pragma",
                      "value": "no-cache"
                    },
                    {
                      "key": "Expires",
                      "value": "0"
                    },
                    {
                      "key": "X-Frame-Options",
                      "value": "DENY"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n    \"access_token\": \"4b5eb7aa-5714-4c73-8813-4e4aae0a3e0f\",\n    \"token_type\": \"bearer\",\n    \"expires_in\": 2579,\n    \"scope\": \"api\",\n    \"Roles\": [],\n    \"FirstName\": \"Bob\",\n    \"LastName\": \"Smith\"\n}"
                }
              ]
            },
            {
              "name": "Fluent Auth - Current Retailer Admin User",
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const utils = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.utils\"));",
                      "const env_manager = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.env_manager\"));",
                      "",
                      "const jsonData = pm.response.json();",
                      "",
                      "let retailer_ref = pm.environment.get(\"fluent.retailer.current.ref\");",
                      "env_manager.setTokenVars(`fluent.retailer.${retailer_ref}`, jsonData);",
                      "env_manager.setCurrentRetailer(retailer_ref);",
                      "",
                      "// const jsonData = pm.response.json();",
                      "// pm.environment.set(\"fluent.retailer.current.token\", jsonData.access_token);",
                      "",
                      "// var expiryTime = new Date(Date.now() + (jsonData.expires_in * 1000));",
                      "// console.log(\"Token will expire at: \" + expiryTime);",
                      "// pm.environment.set(\"fluent.retailer.current.token.expiry_time\", expiryTime);",
                      ""
                    ],
                    "type": "text/javascript"
                  }
                },
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "if (!pm.environment.has(\"fluent.retailer.current.ref\")) {",
                      "    throw Error(\"No Current Retailer Set.\");",
                      "}"
                    ],
                    "type": "text/javascript"
                  }
                }
              ],
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "header": [],
                "url": {
                  "raw": "{{fluent.account.host}}/oauth/token?username={{fluent.retailer.current.user.username}}&password={{fluent.retailer.current.user.password}}&client_id={{fluent.account.client_id}}&client_secret={{fluent.account.client_secret}}&scope=api&grant_type=password",
                  "host": [
                    "{{fluent.account.host}}"
                  ],
                  "path": [
                    "oauth",
                    "token"
                  ],
                  "query": [
                    {
                      "key": "username",
                      "value": "{{fluent.retailer.current.user.username}}",
                      "description": "Fluent Retailer User Username"
                    },
                    {
                      "key": "password",
                      "value": "{{fluent.retailer.current.user.password}}",
                      "description": "Fluent Retailer User Password"
                    },
                    {
                      "key": "client_id",
                      "value": "{{fluent.account.client_id}}",
                      "description": "Fluent Account Id / Client Id"
                    },
                    {
                      "key": "client_secret",
                      "value": "{{fluent.account.client_secret}}",
                      "description": "Fluent Account Client Secret"
                    },
                    {
                      "key": "scope",
                      "value": "api"
                    },
                    {
                      "key": "grant_type",
                      "value": "password"
                    }
                  ]
                },
                "description": "## Authenticate the Current Retailer Admin User\n\nUse this request to Authenticate your Current Retailer Admin User, based on the Retailer currently set on the `fluent.retailer.current.ref` variable in the JetPack compatible Environment File.\n\nThe response `access_token` will be saved into the `fluent.retailer.current.token` environment variable for use in future requests.\n\nFor more information: [Fluent API Authentication](https://lingo.fluentcommerce.com/DEVELOPERS/authentication/)"
              },
              "response": [
                {
                  "name": "Fluent Auth - Account: SUCCESS",
                  "originalRequest": {
                    "method": "POST",
                    "header": [],
                    "url": {
                      "raw": "{{fluent.account.host}}/oauth/token?username={{fluent.account.username}}&password={{fluent.account.password}}&client_id={{fluent.account.client_id}}&client_secret={{fluent.account.client_secret}}&scope=api&grant_type=password",
                      "host": [
                        "{{fluent.account.host}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ],
                      "query": [
                        {
                          "key": "username",
                          "value": "{{fluent.account.username}}",
                          "description": "Fluent Account Admin User Username"
                        },
                        {
                          "key": "password",
                          "value": "{{fluent.account.password}}",
                          "description": "Fluent Account Admin User Password"
                        },
                        {
                          "key": "client_id",
                          "value": "{{fluent.account.client_id}}",
                          "description": "Fluent Account Id / Client Id"
                        },
                        {
                          "key": "client_secret",
                          "value": "{{fluent.account.client_secret}}",
                          "description": "Fluent Account Client Secret"
                        },
                        {
                          "key": "scope",
                          "value": "api"
                        },
                        {
                          "key": "grant_type",
                          "value": "password"
                        }
                      ]
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Date",
                      "value": "Tue, 29 Oct 2019 00:45:57 GMT"
                    },
                    {
                      "key": "Content-Type",
                      "value": "application/json;charset=UTF-8"
                    },
                    {
                      "key": "Transfer-Encoding",
                      "value": "chunked"
                    },
                    {
                      "key": "Connection",
                      "value": "keep-alive"
                    },
                    {
                      "key": "Server",
                      "value": "nginx/1.10.3 (Ubuntu)"
                    },
                    {
                      "key": "Access-Control-Allow-Origin",
                      "value": "*"
                    },
                    {
                      "key": "Access-Control-Allow-Methods",
                      "value": "POST, PUT, GET, OPTIONS, DELETE"
                    },
                    {
                      "key": "Access-Control-Max-Age",
                      "value": "3600"
                    },
                    {
                      "key": "Access-Control-Allow-Headers",
                      "value": "Authorization, Content-Type, fluent.account"
                    },
                    {
                      "key": "Access-Control-Expose-Headers",
                      "value": "flex.type, flex.version"
                    },
                    {
                      "key": "Access-Control-Allow-Credentials",
                      "value": "true"
                    },
                    {
                      "key": "X-Content-Type-Options",
                      "value": "nosniff"
                    },
                    {
                      "key": "X-XSS-Protection",
                      "value": "1; mode=block"
                    },
                    {
                      "key": "Cache-Control",
                      "value": "no-cache, no-store, max-age=0, must-revalidate"
                    },
                    {
                      "key": "Cache-Control",
                      "value": "no-store"
                    },
                    {
                      "key": "Pragma",
                      "value": "no-cache"
                    },
                    {
                      "key": "Pragma",
                      "value": "no-cache"
                    },
                    {
                      "key": "Expires",
                      "value": "0"
                    },
                    {
                      "key": "X-Frame-Options",
                      "value": "DENY"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n    \"access_token\": \"4b5eb7aa-5714-4c73-8813-4e4aae0a3e0f\",\n    \"token_type\": \"bearer\",\n    \"expires_in\": 2579,\n    \"scope\": \"api\",\n    \"Roles\": [],\n    \"FirstName\": \"Bob\",\n    \"LastName\": \"Smith\"\n}"
                }
              ]
            }
          ],
          "description": "This Authentication Request is set to authenticate the B2C Retailer Admin User.\n\nThis request will set the `fluent.retailer.current.token` which is used by the following requests.\n\nThis effectively activates the current Retailer for the given Lab steps to be executed."
        },
        {
          "name": "View Workflows",
          "item": [
            {
              "name": "Get Retailer Workflows",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{fluent.account.host}}/api/v4.1/workflow?retailerId={{fluent.retailer.current.id}}",
                  "host": [
                    "{{fluent.account.host}}"
                  ],
                  "path": [
                    "api",
                    "v4.1",
                    "workflow"
                  ],
                  "query": [
                    {
                      "key": "retailerId",
                      "value": "{{fluent.retailer.current.id}}",
                      "description": "The ID of the current Retailer"
                    },
                    {
                      "key": "count",
                      "value": "50",
                      "description": "The number of records to return per page.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Returns the latest workflow version for the given Retailer and Type"
              },
              "response": []
            }
          ]
        },
        {
          "name": "Create Simple HD & CC Orders",
          "item": [
            {
              "name": "Create Customer",
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const jsonData = pm.response.json();",
                      "",
                      "if(jsonData.errors) {",
                      "    throw new Error(\"Errors returned in reponse: \" + JSON.stringify(jsdonData.errors));",
                      "}",
                      "",
                      "pm.environment.set(\"fluent.retailer.current.customer.id\", jsonData.data.createCustomer.id);",
                      "pm.environment.set(\"fluent.retailer.\" + pm.environment.get(\"fluent.retailer.current.ref\") + \".customer.id\", jsonData.data.createCustomer.id);",
                      ""
                    ],
                    "type": "text/javascript"
                  }
                }
              ],
              "request": {
                "auth": {
                  "type": "bearer",
                  "bearer": [
                    {
                      "key": "token",
                      "value": "{{fluent.retailer.current.token}}",
                      "type": "string"
                    }
                  ]
                },
                "method": "POST",
                "header": [],
                "body": {
                  "mode": "graphql",
                  "graphql": {
                    "query": "mutation createCustomer ($retailerId: ID!, $customerEmail: String!) {\n    createCustomer(input: {\n        username: $customerEmail,\n        title: \"{{$randomNameTitle}}\",\n        firstName: \"{{$randomFirstName}}\",\n        lastName: \"{{$randomLastName}}\",\n        primaryEmail: $customerEmail,\n        promotionOptIn: false,\n        timezone: \"\",\n        retailer: {\n            id: $retailerId\n        }\n    }) {\n        id\n    }\n}\n",
                    "variables": "{\n\t\"retailerId\": {{fluent.retailer.current.id}},\n\t\"customerEmail\": \"{{$randomEmail}}\"\n}"
                  }
                },
                "url": {
                  "raw": "{{fluent.account.host}}/graphql",
                  "host": [
                    "{{fluent.account.host}}"
                  ],
                  "path": [
                    "graphql"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Create CC Order",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "pm.environment.set(\"order_unique_ref\", _.random(1000, 9999));",
                      "",
                      "// let use_unique_suffix = (pm.environment.has(\"fluent.data.use_unique_suffix\") && pm.environment.get(\"fluent.data.use_unique_suffix\") == true) ? true : false;",
                      "",
                      "",
                      "// if (use_unique_suffix) {",
                      "//     pm.variables.set(\"product_catalogue_ref\", \"FCRG\" + pm.environment.get(\"fluent.data.unique_suffix\") + \":PC:MASTER\");",
                      "//     pm.variables.set(\"pickup_location_ref\", \"F\" + pm.environment.get(\"fluent.data.unique_suffix\") + \"_SYD\");",
                      "// } else {",
                      "    // pm.variables.set(\"product_catalogue_ref\", \"PC:MASTER:\" + pm.environment.get(\"fluent.retailer.current.id\"));",
                      "    // // pm.variables.set(\"product_catalogue_ref\", \"FCRG:PC:MASTER\");",
                      "    // pm.variables.set(\"pickup_location_ref\", \"B2C_SYD_\" + pm.environment.get(\"fluent.retailer.current.id\"));",
                      "// }",
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const jsonData = pm.response.json();",
                      "",
                      "if(jsonData.errors) {",
                      "    throw new Error(\"Errors returned in reponse: \" + JSON.stringify(jsdonData.errors));",
                      "}",
                      "",
                      "pm.environment.set(\"fluent.retailer.current.order.last_id\", jsonData.data.createOrder.id);",
                      "pm.environment.set(\"fluent.retailer.current.order.last_ref\", jsonData.data.createOrder.ref);",
                      "",
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {}
                  }
                }
              ],
              "request": {
                "method": "POST",
                "header": [],
                "body": {
                  "mode": "graphql",
                  "graphql": {
                    "query": "mutation createSimpleCCOrder ($retailerId: ID!, $customerId: ID!, $orderRef: String!, $orderItemRef: String!, $productCatalogueRef: String!, $productRef: String!, $fulfilmentType: String!, $pickupLocationRef: String!) {\n    createOrder(input: {\n        ref: $orderRef,\n        retailer: { id: $retailerId },\n        type: \"CC\",\n        customer: { id: $customerId },\n    \ttotalPrice: 80.00,\n        items: [{\n            ref: $orderItemRef,\n            productRef: $productRef,\n            productCatalogueRef: $productCatalogueRef,\n            price: 80.00,\n            paidPrice: 80.00,\n            totalPrice: 80.00,\n            taxPrice: 8.00,\n            totalTaxPrice: 8.00,\n            quantity: 1,\n          \tcurrency:\"USD\"\n        }],\n        fulfilmentChoice: {\n            currency: \"USD\",\n            deliveryType: \"STANDARD\",\n            fulfilmentPrice: 5.00,\n            fulfilmentTaxPrice: 0.99,\n            fulfilmentType: $fulfilmentType\n            pickupLocationRef: $pickupLocationRef\n        }\n    }) {\n        id\n        ref\n    }\n}\n",
                    "variables": "{\n\t\"retailerId\": {{fluent.retailer.current.id}},\n\t\"customerId\": {{fluent.retailer.current.customer.id}},\n\t\"orderRef\": \"CC_{{order_unique_ref}}\",\n\t\"orderItemRef\": \"AH8050-002\",\n\t\"productCatalogueRef\": \"PC:MASTER:{{fluent.retailer.current.id}}\",\n\t\"productRef\": \"AH8050-002\",\n\t\"fulfilmentType\": \"CC_PFS\",\n\t\"pickupLocationRef\": \"B2C_SYD_{{fluent.retailer.current.id}}\"\n}"
                  }
                },
                "url": {
                  "raw": "{{fluent.account.host}}/graphql",
                  "host": [
                    "{{fluent.account.host}}"
                  ],
                  "path": [
                    "graphql"
                  ]
                },
                "description": "Workaround: Item Ref MUST be = Product Ref"
              },
              "response": []
            },
            {
              "name": "Create HD Order",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "pm.environment.set(\"order_unique_ref\", _.random(1000, 9999));",
                      "",
                      "// let use_unique_suffix = (pm.environment.has(\"fluent.data.use_unique_suffix\") && pm.environment.get(\"fluent.data.use_unique_suffix\") == true) ? true : false;",
                      "",
                      "// if (use_unique_suffix) {",
                      "//     pm.variables.set(\"product_catalogue_ref\", \"FCRG\" + pm.environment.get(\"fluent.data.unique_suffix\") + \":PC:MASTER\");",
                      "// } else {",
                      "//     pm.variables.set(\"product_catalogue_ref\", \"PC:MASTER:1\");",
                      "//     // pm.variables.set(\"product_catalogue_ref\", \"FCRG:PC:MASTER\");",
                      "// }",
                      "",
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const jsonData = pm.response.json();",
                      "",
                      "if (jsonData.errors) {",
                      "    throw new Error(\"Errors returned in reponse: \" + JSON.stringify(jsdonData.errors));",
                      "}",
                      "",
                      "pm.environment.set(\"fluent.retailer.current.order.last_id\", jsonData.data.createOrder.id);",
                      "pm.environment.set(\"fluent.retailer.current.order.last_ref\", jsonData.data.createOrder.ref);",
                      "",
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {}
                  }
                }
              ],
              "request": {
                "method": "POST",
                "header": [],
                "body": {
                  "mode": "graphql",
                  "graphql": {
                    "query": "mutation createSimpleHDOrder($retailerId: ID!, $customerId: ID!, $orderRef: String!, $orderItemRef: String!, $productCatalogueRef: String!, $productRef: String!) {\n    createOrder (input: {\n        ref: $orderRef,\n        retailer: { id: $retailerId },\n        type: \"HD\",\n        customer: { id: $customerId },\n        totalPrice: 200.00,\n        totalTaxPrice: 20.00 ,\n        items: [{\n            ref: $orderItemRef,\n            productRef: $productRef,\n            productCatalogueRef:$productCatalogueRef,\n            price: 200.00,\n            paidPrice: 200.00,\n            totalPrice: 200.00,\n            taxPrice: 20.00,\n            totalTaxPrice: 20.00,\n            quantity: 1,\n            currency: \"AUD\"\n        }], \n        fulfilmentChoice: {\n            currency: \"AUD\",\n            deliveryType: \"STANDARD\",\n            fulfilmentPrice: 5,\n            fulfilmentTaxPrice: 0.99,\n            deliveryAddress: {\n                ref: \"{{$randomUUID}}\",\n                name: \"{{$randomFullName}}\",\n                companyName: \"{{$randomCompanyName}}\", \n                street: \"46 Kippax street\",\n                city: \"Surry Hills\",\n                state: \"NSW\",\n                postcode: \"2060\",\n                country: \"Australia\",\n                latitude: -33.884620,\n                longitude: 151.209760\n            }\n        }\n        \n    }) {\n        id\n        ref\n    }\n}\n",
                    "variables": "{\n\t\"retailerId\": {{fluent.retailer.current.id}},\n\t\"customerId\": {{fluent.retailer.current.customer.id}},\n\t\"orderRef\": \"HD_{{order_unique_ref}}\",\n\t\"orderItemRef\": \"AH8050-001\",\n\t\"productCatalogueRef\": \"PC:MASTER:{{fluent.retailer.current.id}}\",\n\t\"productRef\": \"AH8050-001\"\n}"
                  }
                },
                "url": {
                  "raw": "{{fluent.account.host}}/graphql",
                  "host": [
                    "{{fluent.account.host}}"
                  ],
                  "path": [
                    "graphql"
                  ]
                }
              },
              "response": []
            }
          ]
        }
      ]
    }
  ],
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{fluent.retailer.current.token}}",
        "type": "string"
      }
    ]
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// Validations",
          "if (!pm.environment.get(\"fluent.account.host\")",
          "    || !pm.environment.get(\"fluent.account.username\")",
          "    || !pm.environment.get(\"fluent.account.password\")",
          "    || !pm.environment.get(\"fluent.account.client_id\")",
          "    || !pm.environment.get(\"fluent.account.client_secret\")",
          ") {",
          "    throw new Error(\"Please select a valid Enviroment prior to executing this request!\");",
          "}",
          "",
          "// Set Headers",
          "pm.request.headers.add(\"application/json\", \"Content-Type\");",
          "if (pm.environment.get(\"fluent.account.client_id\")) {",
          "    pm.request.headers.add(pm.environment.get(\"fluent.account.client_id\"), \"fluent.account\");",
          "}",
          "",
          "// Load Fluent JetPack Scripts:",
          "if (!pm.collectionVariables.has(\"fluent.jetpack.postman.loaded\")) {",
          "",
          "    console.log(\"Loading JetPack Postman Scripts...\");",
          "",
          "    let jetpack_server_host = pm.environment.has(\"fluent.jetpack.server.host\") ? pm.environment.get(\"fluent.jetpack.server.host\") : \"http://localhost:3001\";",
          "    // Load Utils",
          "    pm.sendRequest(jetpack_server_host + \"/postman-helpers/utils\", (err, res) => {",
          "        if (res.code !== 200) {",
          "            console.warn(\"Failed to load Fluent JetPack Postman Utils, Response Code: \" + res.code);",
          "            postman.setNextRequest(null);",
          "            throw Error(\"Failed to load Fluent JetPack Postman Utils, Response Code: \" + res.code + \", Response: \" + res.text());",
          "        }",
          "        pm.collectionVariables.set(\"fluent.jetpack.postman.utils\", res.text() + \"; loadUtils();\");",
          "        let temp_utils = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.utils\"));",
          "        temp_utils.hello();",
          "    });",
          "",
          "    // Load Environemnt Manager",
          "    pm.sendRequest(jetpack_server_host + \"/postman-helpers/env_manager\", (err, res) => {",
          "        if (res.code !== 200) {",
          "            console.warn(\"Failed to load Fluent JetPack Postman Environment Manager, Response Code: \" + res.code);",
          "            postman.setNextRequest(null);",
          "            throw Error(\"Failed to load Fluent JetPack Postman Environment Manager, Response Code: \" + res.code + \", Response: \" + res.text());",
          "        }",
          "        pm.collectionVariables.set(\"fluent.jetpack.postman.env_manager\", res.text() + \"; loadEnvManager();\");",
          "        let temp_env_manager = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.env_manager\"));",
          "        temp_env_manager.hello();",
          "    });",
          "",
          "    // Load Runner",
          "    // pm.sendRequest(jetpack_server_host + \"/postman-helpers/runner\", (err, res) => {",
          "    //     if (res.code !== 200) {",
          "    //         console.warn(\"Failed to load Fluent JetPack LaunchPad Runner, Response Code: \" + res.code);",
          "    //         postman.setNextRequest(null);",
          "    //         throw Error(\"Failed to load Fluent JetPack LaunchPad Runner, Response Code: \" + res.code + \", Response: \" + res.text());",
          "    //     }",
          "    //     pm.collectionVariables.set(\"fluent.jetpack.postman.launchpad_runner\", res.text() + \"; loadRunner();\");",
          "    //     let temp_runner = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.launchpad_runner\"));",
          "    //     temp_runner.hello();",
          "    // });",
          "",
          "    // Load Test Utils",
          "    pm.sendRequest(jetpack_server_host + \"/postman-helpers/test_utils\", (err, res) => {",
          "        if (res.code !== 200) {",
          "            console.warn(\"Failed to load Fluent JetPack Test Utils, Response Code: \" + res.code);",
          "            postman.setNextRequest(null);",
          "            throw Error(\"Failed to load Fluent JetPack Test Utils, Response Code: \" + res.code + \", Response: \" + res.text());",
          "        }",
          "        pm.collectionVariables.set(\"fluent.jetpack.postman.test_utils\", res.text() + \"; loadTestUtils();\");",
          "        let temp_test_utils = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.test_utils\"));",
          "        temp_test_utils.hello();",
          "    });",
          "",
          "    // Load Visualiser Utils",
          "    pm.sendRequest(jetpack_server_host + \"/postman-helpers/visualiser_utils\", (err, res) => {",
          "        if (res.code !== 200) {",
          "            console.warn(\"Failed to load Fluent JetPack Visualiser Utils, Response Code: \" + res.code);",
          "            postman.setNextRequest(null);",
          "            throw Error(\"Failed to load Fluent JetPack Visualiser Utils, Response Code: \" + res.code + \", Response: \" + res.text());",
          "        }",
          "        pm.collectionVariables.set(\"fluent.jetpack.postman.visualiser_utils\", res.text() + \"; loadVisualiserUtils();\");",
          "        let temp_visualiser_utils = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.visualiser_utils\"));",
          "        temp_visualiser_utils.hello();",
          "    });",
          "",
          "    // Load Visualiser Templates",
          "    pm.sendRequest(jetpack_server_host + \"/postman-helpers/visualiser_templates\", (err, res) => {",
          "        if (res.code !== 200) {",
          "            console.warn(\"Failed to load Fluent JetPack Visualiser Templates, Response Code: \" + res.code);",
          "            postman.setNextRequest(null);",
          "            throw Error(\"Failed to load Fluent JetPack Visualiser Templates, Response Code: \" + res.code + \", Response: \" + res.text());",
          "        }",
          "        pm.collectionVariables.set(\"fluent.jetpack.postman.visualiser_templates\", res.text() + \"; loadVisualiserTemplates();\");",
          "        let temp_visualiser_templates = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.visualiser_templates\"));",
          "        temp_visualiser_templates.hello();",
          "    });",
          "",
          "    pm.collectionVariables.set(\"fluent.jetpack.postman.loaded\", true);",
          "    // console.log(\"JetPack Postman Scripts successfully Loaded!\");",
          "}",
          ""
        ]
      }
    },
    {
      "listen": "test",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// Standard Tests",
          "const test_utils = eval(pm.collectionVariables.get(\"fluent.jetpack.postman.test_utils\"));",
          "test_utils.standardTests();",
          ""
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "fluent.learning.labs.version",
      "value": "v2022.01.1"
    },
    {
      "key": "fluent.jetpack.postman.env_manager",
      "value": "/**\n * Returns an instance of the Fluent JetPack Postman Environment Manager Utility\n * \n * @version 1.2020.7.0\n * @exports fluent-jetpack-postman/env_manager\n * @namespace env_manager\n * @author: Lesley Dean <lesley.dean@fluentcommerce.com>\n */\nfunction loadEnvManager() {\n    let env_manager = {};\n    \n    /**\n     * Returns a welcome message to confirm the Environment Manager is active.\n     * \n     * @memberof env_manager\n     * @method hello\n     * \n     * @returns {string}\n     */\n    env_manager.hello = () => {\n        console.info(\"Hello from Fluent JetPack Postman Env Manager!\");\n    };\n    \n    /**\n     * Stores the token, and the token expiry time in the Environment Variables.\n     * \n     * @memberof env_manager\n     * @method setTokenVars\n     * \n     * @param {string} `token_env_key_prefix` The Prefix of the Environment Variable Key for the token.\n     * @param {object} `jsonData` The JSON Response Data from the Authentication Request.\n     */\n    env_manager.setTokenVars = (token_env_key_prefix, jsonData) => {\n        pm.environment.set(token_env_key_prefix + \".token\", jsonData.access_token);\n        var expiryTime = new Date(Date.now() + (jsonData.expires_in * 1000));\n        pm.environment.set(token_env_key_prefix + \".token.expiry_time\", expiryTime);\n        console.info(\"Token '\" + jsonData.access_token + \"' for '\" + token_env_key_prefix + \"' will expire at: \" + expiryTime);\n    };\n    \n    /**\n     * Checks if token stored in the given key has expired or not.\n     * \n     * @memberof env_manager\n     * @method isTokenExpired\n     * \n     * @param {string} `token_env_key` The Environment Variable Key for the token.\n     * @returns {boolean} `true` or `false`\n     */\n    env_manager.isTokenExpired = (token_env_key) => {\n        if (!pm.environment.has(token_env_key)) {\n            return true;\n        }\n        let token = pm.environment.get(token_env_key);\n        let exp_time = pm.environment.get(token_env_key + \".expiry_time\");\n        let iso_utc_now = new Date().toISOString();\n        \n        console.log(\"Token Key: \" + token_env_key + \", Token: \" + token + \", Expiry Time: \" + exp_time + \", Time now: \" + iso_utc_now);\n        // console.log(\"Expiry Time Value: \" + Date.parse(exp_time).valueOf() + \", Time now Value: \" + Date.parse(iso_utc_now).valueOf());\n        \n        if (!exp_time) {\n            return true;\n        }\n        \n        let exp = Date.parse(exp_time).valueOf();\n        let now = Date.parse(iso_utc_now).valueOf();\n        \n        if (exp <= now) {\n            return true;\n        }\n        if ((exp + 5000) <= now) {\n            console.warn(\"Token is expiring soon! Env Key: \" + token_env_key + \", Token: \" + token + \", Expiry Time: \" + exp_time);\n        }\n        return false;\n    };\n    /**\n     * Re-authenticate the user for a given Token Environment Key.\n     * \n     * @memberof env_manager\n     * @method reAuthenticateToken\n     * \n     * @param {string} token_env_key The Environment Variable Key for the token to be re-authenticated. E.g: 'fluent.account.token'\n     */\n    env_manager.reAuthenticateToken = (token_env_key) => {\n    \tlet token_env_key_prefix = token_env_key.substr(0,token_env_key.indexOf(\".token\"));\n    \tconsole.log(\"token_env_key_prefix: \" + token_env_key_prefix);\n    \tlet username_key = (token_env_key_prefix.indexOf(\".retailer\") > 1) ? token_env_key_prefix + \".user.username\" : token_env_key_prefix + \".username\";\n    \tlet password_key = (token_env_key_prefix.indexOf(\".retailer\") > 1) ? token_env_key_prefix + \".user.password\" : token_env_key_prefix + \".password\";\n    \tlet username = pm.environment.get(username_key);\n    \tlet password = pm.environment.get(password_key);\n    \tenv_manager.authenticateUser(token_env_key_prefix, username, password);\n    };\n    /**\n     * Execute the authentication request for the given token key, username, and password.\n     * \n     * @memberof env_manager\n     * @method authenticateUser\n     * \n     * @param {string} token_env_key_prefix The Environment Variable Key Prefix. E.g: 'fluent.account', fluent.account.superuser', 'fluent.retailer.fc_fashion'\n     * @param {string} username The Username for the user to be authenticated.\n     * @param {string} password The Password for the user to be authenticated.\n     */\n    env_manager.authenticateUser = (token_env_key_prefix, username, password) => {\n    \tlet auth_url = pm.environment.get(\"fluent.account.host\") \n\t\t\t\t\t    \t+ \"/oauth/token?username=\" + username \n\t\t\t\t\t    \t+ \"&password=\" + password \n\t\t\t\t\t    \t+ \"&client_id=\" + pm.environment.get(\"fluent.account.client_id\") \n\t\t\t\t\t    \t+ \"&client_secret=\" + pm.environment.get(\"fluent.account.client_secret\") \n\t\t\t\t\t    \t+ \"&scope=api&grant_type=password\";\n    \tpm.sendRequest({\n\t\t    url: auth_url,\n\t\t    method: 'POST',\n\t\t    header: {\n\t\t        'content-type': 'application/json',\n\t\t        'fluent.account': pm.environment.get(\"fluent.account.client_id\")\n\t\t    }\n\t\t}, (err, res) => {\n    \t\tif (res.code !== 200) {\n    \t\t\tthrow Error(\"Unable to authenticate user: \" + username + \" - Error occurred: \" + res.code + \", Response: \" + res.text());\n    \t\t}\n    \t\tenv_manager.setTokenVars(token_env_key_prefix, res.json())\n    \t});\n    };\n    /** \n     * Sets the `fluent.retailer.current` prefixed Environment Variables for the given `retailer_ref`.\n     * \n     * @memberof env_manager\n     * @method setCurrentRetailer\n     * \n     * @param {string} `retailer_ref` The Reference of the Retailer to activate as \"Current\".\n     */\n    env_manager.setCurrentRetailer = (retailer_ref) => {\n        console.log(\"About to set current Retailer to: \" + retailer_ref);\n        let retailer_id = pm.environment.get(utils.getEnvKeyForRetailer(retailer_ref, \"id\"));\n        let retailer_username = pm.environment.get(utils.getEnvKeyForRetailer(retailer_ref, \"user.username\"));\n        let retailer_password = pm.environment.get(utils.getEnvKeyForRetailer(retailer_ref, \"user.password\"));\n        let retailer_token = pm.environment.get(utils.getEnvKeyForRetailer(retailer_ref, \"token\"));\n        let retailer_tokenexpiry = pm.environment.get(utils.getEnvKeyForRetailer(retailer_ref, \"token.expiry_time\"));\n        \n        pm.environment.set(\"fluent.retailer.current.ref\", retailer_ref);\n        pm.environment.set(\"fluent.retailer.current.id\", retailer_id);\n        pm.environment.set(\"fluent.retailer.current.user.username\", retailer_username);\n        pm.environment.set(\"fluent.retailer.current.user.password\", retailer_password);\n        pm.environment.set(\"fluent.retailer.current.token\", retailer_token);\n        pm.environment.set(\"fluent.retailer.current.token.expiry_time\", retailer_tokenexpiry);\n        console.log(\"Current Retailer set to: \" + retailer_ref);\n    };\n    /** \n     * Sets the `fluent.account.current` prefixed Environment Variables for the given Account Environment Prefix (`fluent.account` or `fluent.account.superuser`).\n     * \n     * @memberof env_manager\n     * @method setCurrentAccountUser\n     * \n     * @param {string} `account_env_prefix` Either `fluent.account` or `fluent.account.superuser` to activate as \"Current\".\n     */\n    env_manager.setCurrentAccountUser = (account_env_prefix) => {\n        console.log(\"About to set current Account for environment prefix: \" + account_env_prefix);\n        let account_username = pm.environment.get(account_env_prefix + \".username\");\n        let account_password = pm.environment.get(account_env_prefix + \".password\");\n        let account_token = pm.environment.get(account_env_prefix + \".token\");\n        let account_tokenexpiry = pm.environment.get(account_env_prefix + \".token.expiry_time\");\n        \n        pm.environment.set(\"fluent.account.current.env_prefix\", account_env_prefix);\n        pm.environment.set(\"fluent.account.current.user.username\", account_username);\n        pm.environment.set(\"fluent.account.current.user.password\", account_password);\n        pm.environment.set(\"fluent.account.current.token\", account_token);\n        pm.environment.set(\"fluent.account.current.token.expiry_time\", account_tokenexpiry);\n        console.log(\"Current Account User set to: \" + account_username);\n    };\n    /** \n     * Sets the `fluent.location.current` prefixed Environment Variables for the given `location_ref`.\n     * \n     * @memberof env_manager\n     * @method setCurrentLocation\n     * \n     * @param {string} `location_ref` Either `fluent.account` or `fluent.account.superuser` to activate as \"Current\".\n     */\n    env_manager.setCurrentLocation = (location_ref) => {\n        console.log(\"About to set current Location: \" + location_ref);\n        let location_id = pm.environment.get(`fluent.location.${location_ref}.id`);\n        let location_username = pm.environment.get(`fluent.location.${location_ref}.user.username`);\n        let location_password = pm.environment.get(`fluent.location.${location_ref}.user.password`);\n        let location_token = pm.environment.get(`fluent.location.${location_ref}.token`);\n        let location_tokenexpiry = pm.environment.get(`fluent.location.${location_ref}.token.expiry_time`);\n        \n        pm.environment.set(\"fluent.location.current.ref\", location_ref);\n        pm.environment.set(\"fluent.location.current.id\", location_id);\n        pm.environment.set(\"fluent.location.current.user.username\", location_username);\n        pm.environment.set(\"fluent.location.current.user.password\", location_password);\n        pm.environment.set(\"fluent.location.current.token\", location_token);\n        pm.environment.set(\"fluent.location.current.token.expiry_time\", location_tokenexpiry);\n        console.log(\"Current Location set to: \" + location_ref);\n    };\n    // SaveRetailerInfo\n    env_manager.saveRetailerInfo = (retailer_ref, retailer_id, retailer_username, retailer_password) => {\n        pm.environment.set(utils.getEnvKeyForRetailer(retailer_ref, \"id\"), retailer_id);\n        pm.environment.set(utils.getEnvKeyForRetailer(retailer_ref, \"ref\"), retailer_ref);\n        pm.environment.set(utils.getEnvKeyForRetailer(retailer_ref, \"user.username\"), retailer_username);\n        pm.environment.set(utils.getEnvKeyForRetailer(retailer_ref, \"user.password\"), retailer_password);\n    };\n    // IsMasterRetailerSet\n    env_manager.isMasterRetailerSet = () => {\n        return !(!pm.environment.has(\"fluent.retailer.master.ref\"));\n    };\n    // IsRetailerSet\n    env_manager.isRetailerSet = (retailer_ref) => {\n        return !(!pm.environment.has(utils.getEnvKeyForRetailer(retailer_ref, \"id\")));\n    };\n    // SaveMasterRetailerInfo - to be deprecated in future (current workaround for rules)\n    env_manager.saveMasterRetailerInfo = (retailer_ref, retailer_id, retailer_username, retailer_password) => {\n        console.log(\"About to save master retailer for: \" + retailer_ref);\n        pm.environment.set(\"fluent.retailer.master.id\", retailer_id);\n        pm.environment.set(\"fluent.retailer.master.ref\", retailer_ref);\n        pm.environment.set(\"fluent.retailer.master.user.username\", retailer_username);\n        pm.environment.set(\"fluent.retailer.master.user.password\", retailer_password);\n        console.log(\"Master retailer set: \" + retailer_ref);\n    };\n    /**\n     * Sets the `current_username` and `current_password` fields for the Dynamic Authentication Request.\n     * \n     * @memberof env_manager\n     * @method setAuthCredentials\n     *\n     * @param {string} `username` The Username to set.\n     * @param {string} `password` The Password to set.\n     */\n    env_manager.setAuthCredentials = (username, password) => {\n        console.info(\"Setting Auth Credentials for user: \" + username);\n        pm.variables.set(\"current_username\", username);\n        pm.variables.set(\"current_password\", password);\n    };\n    /**\n     * Clears the `current_username` and `current_password` fields after the Dynamic Authentication Request\n     * \n     * @memberof env_manager\n     * @method clearAuthCredentials\n     */\n    env_manager.clearAuthCredentials = () => {\n        console.info(\"Clearing Auth Credentials for user: \" + pm.variables.get(\"current_username\"));\n\t\tpm.variables.unset(\"current_username\");\n\t\tpm.variables.unset(\"current_password\");\n    };\n    /**\n     * Sets up the 'current_username' and 'current_password' for the upcoming Dynamic Authentication Request.\n     * \n     * @memberof env_manager\n     * @method setDynamicAuth\n     * \n     * @param {string} auth_key_prefix The Environment Variable Key Prefix for the required Authentication. E.g: 'fluent.account', 'fluent.account.superuser', 'fluent.retailer'\n     */\n    env_manager.setDynamicAuth = (auth_key_prefix) => {\n        pm.variables.set(\"current_auth_key_prefix\", auth_key_prefix);\n        switch (auth_key_prefix) {\n            case \"fluent.account\": {\n                // Auth the Default Account Admin User\n                env_manager.setAuthCredentials(pm.environment.get(\"fluent.account.username\"), pm.environment.get(\"fluent.account.password\"));\n                break;\n            }\n            case \"fluent.account.superuser\": {\n                // Auth the Account Super User\n                env_manager.setAuthCredentials(pm.environment.get(\"fluent.account.superuser.username\"), pm.environment.get(\"fluent.account.superuser.password\"));\n                break;\n            }\n            case \"fluent.retailer\": {\n                // Get Retailer Ref from Data File, and retrieve username and password:\n                let retailer_ref = utils.getRetailerRef(data.retailer_ref);\n                let username_key = utils.getEnvKeyForRetailer(retailer_ref, \"user.username\");\n                let password_key = utils.getEnvKeyForRetailer(retailer_ref, \"user.password\");\n                console.log(\"username_key: \" + username_key + \", password_key: \" + password_key);\n                env_manager.setAuthCredentials(pm.environment.get(username_key), pm.environment.get(password_key));\n                break;\n            }\n            default: {\n                throw Error(\"Invalid Auth Key Prefix for Dynamic Auth. Aborting...\");\n            }\n        }\n    };\n    \n    /**\n     * Handles the response from the Dynamic Auth Request to set the Token Variables and Current Retailer\n     * \n     * @memberof env_manager\n     * @method handleAuthResponse\n     * \n     * @param {string} jsonData The JSON Response data from the Auth Request\n     */\n    env_manager.handleAuthResponse = (jsonData) => {\n\t\tconsole.log(\"Handle Dynamic Auth Response - Token: \" + jsonData.access_token);\n        if (!jsonData.access_token) {\n            throw Error(\"Unable to proceed - invalid auth token.\");\n        }\n        env_manager.clearAuthCredentials();\n        let current_auth_key_prefix = pm.variables.get(\"current_auth_key_prefix\");\n        switch (current_auth_key_prefix) {\n            case \"fluent.retailer\": {\n                let retailer_ref = utils.getRetailerRef(data.retailer_ref);\n                if (!retailer_ref) {\n                    env_manager.setTokenVars(current_auth_key_prefix + \".current\", jsonData);\n                } else {\n                    env_manager.setTokenVars(current_auth_key_prefix + \".\" + retailer_ref, jsonData);\n                    env_manager.setCurrentRetailer(retailer_ref);    \n                }\n                break;\n            }\n            default: {\n                env_manager.setTokenVars(current_auth_key_prefix, jsonData);\n                break;\n            }\n        }\n    };\n    /**\n     * Returns a boolean indicating if the account has been initiated.\n     * \n     * @memberof env_manager\n     * @method isAccountInitiated\n     * \n     * @returns {boolean}\n     */\n    env_manager.isAccountInitiated = () => {\n    \treturn (pm.environment.has(\"fluent.account.initiated\")) ? utils.parseBooleanString(pm.environment.get(\"fluent.account.initiated\")) : false;\n    };\n    /**\n     * Set Account Initiated to true / false.\n     * \n     * @memberof env_manager\n     * @method setAccountInitiated\n     *\n     * @param {boolean} `true` or `false`\n     */\n    env_manager.setAccountInitiated = (value) => {\n    \tpm.environment.set(\"fluent.account.initiated\", value);\n    };\n    env_manager.getNumberOfRetailersToInitiate = () => {\n        if (!pm.environment.has(\"retailers_to_initiate\")) {\n            return 0;\n        }\n       \tlet retailer_refs = JSON.parse(pm.environment.get(\"retailers_to_initiate\"));\n        console.log(\"retailers_to_initiate: \" + JSON.stringify(retailer_refs));\n    \treturn retailer_refs.length;\n    };\n    env_manager.addRetailerRefToInitialise = (retailer_ref) => {\n        // console.log(\"About to add Retailer \" + retailer_ref + \" to retailers_to_initiate, has variable: \" + pm.environment.has(\"retailers_to_initiate\"));\n        let retailers_to_initiate = (pm.environment.has(\"retailers_to_initiate\")) ? JSON.parse(pm.environment.get(\"retailers_to_initiate\")) : [];\n        // console.log(\"retailers_to_initiate before add: \" + JSON.stringify(retailers_to_initiate));\n        retailers_to_initiate.push(retailer_ref);\n        pm.environment.set(\"retailers_to_initiate\", JSON.stringify(retailers_to_initiate));\n        // console.log(\"retailers_to_initiate after add: \" + JSON.stringify(retailers_to_initiate));\n    };\n    env_manager.removeRetailerRefToInitialise = (retailer_ref) => {\n        let retailers_to_initiate = (pm.environment.has(\"retailers_to_initiate\")) ? JSON.parse(pm.environment.get(\"retailers_to_initiate\")) : [];\n        // console.log(\"About to remove retailer ref \" + retailer_ref + \" from the retailers_to_initiate list: \" + JSON.stringify(retailers_to_initiate) + \" Index in array: \" + retailers_to_initiate.indexOf(retailer_ref));\n        retailers_to_initiate.splice(retailers_to_initiate.indexOf(retailer_ref), 1);\n        // console.log(\"retailers_to_initiate after remove: \" + JSON.stringify(retailers_to_initiate) + \", length: \" + retailers_to_initiate.length);\n        if (retailers_to_initiate.length === 0) {\n            pm.environment.unset(\"retailers_to_initiate\");\n        } else {\n            pm.environment.set(\"retailers_to_initiate\", JSON.stringify(retailers_to_initiate));\n        }\n    };\n    env_manager.getNextRetailerRefToInitialise = () => {\n        let retailers_to_initiate = (pm.environment.has(\"retailers_to_initiate\")) ? JSON.parse(pm.environment.get(\"retailers_to_initiate\")) : [];\n        return retailers_to_initiate[0];\n    };\n    env_manager.hasMoreRetailersToInitialise = () => {\n        return (env_manager.getNumberOfRetailersToInitiate() > 0)\n    };\n    env_manager.validatePasswordChangeRequest = (user_kind, user_kind_ref, username, old_pass) => {\n        switch (user_kind) {\n            case \"ACCOUNT\":\n                switch (username) {\n                    case pm.environment.get(\"fluent.account.username\"):\n                        env_manager.saveOldPass(\"fluent.account.password\", old_pass);\n                        break;\n                    case pm.environment.get(\"fluent.account.superuser.username\"):\n                        env_manager.saveOldPass(\"fluent.account.superuser.password\", old_pass);\n                        break;\n                    default:\n                        throw Error(\"Unable to find Account Environment Variable for username: \" + username);\n                }\n                break;\n            case \"RETAILER\":\n                let ret_user = pm.environment.get(`fluent.retailer.${user_kind_ref}.user.username`);\n                if (username != ret_user) {\n                    throw Error(\"Unable to find Retailer Environment Variable for username: \" + username);\n                }\n                env_manager.saveOldPass(`fluent.retailer.${user_kind_ref}.user.password`, old_pass);\n                break;\n            case \"LOCATION\":\n                let loc_user = pm.environment.get(`fluent.location.${user_kind_ref}.user.username`);\n                if (username != loc_user) {\n                    throw Error(\"Unable to find Location Environment Variable for username: \" + username);\n                }\n                env_manager.saveOldPass(`fluent.location.${user_kind_ref}.user.password`, old_pass);\n                break;\n            default:\n                throw Error(\"Please specify the User Kind in the Request Body so that Mission Control can validate and update the correct JetPack Environment Variables.\");\n        }\n    };\n    /**\n     * Validates and saves the old password in an Environment Variable `fluent.account.user.<USERNAME>.password.old`\n     * \n     * @memberof env_manager\n     * @method saveOldPass\n     *\n     * @param {string} password_env_var - The current User Password Environment Variable key\n     * @param {string} old_pass - The old password of the user\n     */\n    env_manager.saveOldPass = (password_env_var, old_pass) => {\n        if (old_pass === pm.environment.get(password_env_var)) {\n            pm.environment.set(`fluent.account.user.${username}.password.old`, old_pass);\n            pm.variables.set(\"update_user_env_var\", password_env_var);\n        } else {\n            throw Error(\"Old Password is incorrect!\");\n        }\n    };\n    /**\n     * Saves the Plugin Info from the Upload Plugin Request into the Environment File.\n     * \n     * @memberof env_manager\n     * @method savePluginInfo\n     *\n     */\n    env_manager.savePluginInfo = () => {\n        const request_json = JSON.stringify(pm.request.body.formdata);\n        const req = JSON.parse(request_json);\n        var filename = req[0].src;\n        var jar_filename_start = filename.lastIndexOf(\"/\") + 1;\n        var from_jar_filename_start = filename.substr(jar_filename_start);\n        var jar_filename_end = from_jar_filename_start.indexOf(\".jar\");\n        var jar_filename = from_jar_filename_start.substr(0,jar_filename_end);\n        console.log(\"jar_filename: \" + jar_filename);\n        var is_dash_snapshot = jar_filename.indexOf(\"-SNAPSHOT\");\n        var is_dash_release = jar_filename.indexOf(\"-RELEASE\");\n        var jar_filename_without_dash_version = jar_filename;\n        var last_dash = jar_filename.lastIndexOf(\"-\");\n        if (is_dash_snapshot > 0 || is_dash_release > 0) {\n            jar_filename_without_dash_version = jar_filename.substr(0,last_dash);\n            last_dash = jar_filename_without_dash_version.lastIndexOf(\"-\");\n        }\n        var plugin_artefact_name = jar_filename.substr(0,last_dash);\n        var plugin_artefact_version = jar_filename.substr(last_dash + 1);\n        var plugin_name = plugin_artefact_name.substr(plugin_artefact_name.lastIndexOf(\"-\")+1);\n        console.log(\"plugin_name: \" + plugin_name);\n        console.log(\"version: \" + plugin_artefact_version);\n        var bundlename = pm.environment.get(\"fluent.account.client_id\") + \".\" + plugin_name + \"::\" + plugin_artefact_version;\n        pm.environment.set(\"fluent.account.plugin.last_artefact_id\", plugin_artefact_name);\n        pm.environment.set(\"fluent.account.plugin.last_artefact_version\", plugin_artefact_version);\n        pm.environment.set(\"fluent.account.plugin.last_plugin_name\", plugin_name);\n        pm.environment.set(\"fluent.account.plugin.last_bundle_name\", bundlename);\n        pm.environment.set(\"fluent.account.plugin.\" + plugin_artefact_name + \".version\", plugin_artefact_version);\n        pm.environment.set(\"fluent.account.plugin.\" + plugin_artefact_name + \".name\", plugin_name);\n        pm.environment.set(\"fluent.account.plugin.\" + plugin_artefact_name + \".bundle_name\", bundlename);\n        // TODO: Get regex version to work...\n        //var reg =  \"(?:(\\d+)\\.)?(?:(\\d+)\\.)?(?:(\\d+)\\.\\d+)\";\n        // var plugin_version = jar_filename.match(reg);\n        // console.log(\"plugin_version: \" + plugin_version);\n        // console.log(\"plugin_version[0]: \" + plugin_version[0]);\n    };\n    return env_manager;\n}; loadEnvManager();"
    },
    {
      "key": "fluent.jetpack.postman.loaded",
      "value": "true"
    },
    {
      "key": "fluent.jetpack.postman.utils",
      "value": "/**\n * Returns an instance of the Fluent JetPack Postman Utility\n * \n * @fileOverview A set of Utility Methods to support the Fluent JeptPack Postman Collections\n * @version 1.2020.7.0\n * @exports fluent-jetpack-postman/utils\n * @namespace utils\n * @author: Lesley Dean <lesley.dean@fluentcommerce.com>\n */\nfunction loadUtils() {\n    let utils = {};\n    \n    /**\n     * Returns a welcome message to confirm the Utils are active.\n     * \n     * @memberof utils\n     * @method hello\n     * \n     * @returns {string}\n     */\n    utils.hello = () => {\n        console.info(\"Hello from Fluent JetPack Utils!\");\n    };\n    \n    /**\n     * Returns a random string of alphanumeric characters.\n     * \n     * @memberof utils\n     * @method getRandomString\n     *\n     * @param {number} length The length of string to return. Default: 8\n     * @returns {string} A Random String of AlphaNumeric Characters.\n     */\n    utils.getRandomString = (length) => {\n        let len = (!length) ? 8 : length;\n        // return Math.random().toString(36).substr(2, len);\n        return Math.random().toString(36).slice(len*-1);\n    };\n    /**\n     * Capitalises the first letter of the given string.<br/>\n     * <br/>\n     * Example:<br/>\n     * \n     * Input: foo bar<br/>\n     * Output: Foo bar\n     * \n     * @memberof utils\n     * @method capitalizeFirstLetter\n     *\n     * @param {string} str The string to return with the first letter capitalised.\n     * @returns {string} \n     */\n    utils.capitalizeFirstLetter = (str) => {\n        return str[0].toUpperCase() + str.slice(1);    \n    };\n    \n    /**\n     * Utility method for logging the Response body of a Request.\n     * \n     * @memberof utils\n     * @method logResponseBody\n     *\n     * @param {string} request_name The name of the Request for which the Response came from.\n     * @param {object} jsonData The JSON Response Data returned by the Request.\n     */\n    utils.logResponseBody = (request_name, jsonData) => {\n        console.log(\"Response for '\" + request_name + \"': \" + JSON.stringify(jsonData));\n    };\n    \n    /**\n     * Utility method for retrieving the parsed value of the Retailer Ref if using the `fluent.data.unique_suffix` Environment Variable for re-runs.\n     * \n     * @memberof utils\n     * @method getRetailerRef\n     *\n     * @param {string} retailer_ref The Reference of the Retailer.\n     * @param {string} field The name of the field of the Retailer Environment Variables. E.g.: 'id', 'user.username', 'token', etc.\n     * @returns {string} The parsed Retailer Reference.\n     */\n    utils.getRetailerRef = (data_retailer_ref) => {\n        if (data_retailer_ref.indexOf(\"unique_suffix\") > 0) {\n            return data_retailer_ref.substr(0, data_retailer_ref.indexOf(\"{{\")) + pm.environment.get(\"fluent.data.unique_suffix\");\n        }\n        return data_retailer_ref;\n    }\n    \n    /**\n     * Utility method for retrieving the Environment Variable Key for the given Retailer Ref.\n     * \n     * @memberof utils\n     * @method getEnvKeyForRetailer\n     *\n     * @param {string} retailer_ref The Reference of the Retailer.\n     * @param {string} field The name of the field of the Retailer Environment Variables. E.g.: 'id', 'user.username', 'token', etc.\n     * @returns {string} Environment Variable Key for Retailer. E.g.: `fluent.retailer.fc_fashion.id`\n     */\n    utils.getEnvKeyForRetailer = (retailer_ref, field) => {\n        let ret_ref = utils.getRetailerRef(retailer_ref);\n        return \"fluent.retailer.\" + ret_ref + \".\" + field;\n    };\n    /**\n     * Utility method for ensuring simple case-insensitive comparison of a boolean value.\n     * \n     * @memberof utils\n     * @method parseBooleanString\n     *\n     * @param {string} string_boolean The String Boolean Value.\n     * @returns {boolean} `true` or `false`\n     */\n    utils.parseBooleanString = (string_boolean) => {\n        return (string_boolean.toString().toLowerCase() === \"true\");\n    };\n    /**\n     * Utility method for returning a Boolean value from a String, or null.\n     * \n     * @memberof utils\n     * @method getBooleanValueOrNull\n     *\n     * @param {string} string_boolean The String Boolean Value.\n     * @returns {boolean} `true` or `false` or `null`\n     */\n    utils.getBooleanValueOrNull = (string_boolean) => {\n        if (string_boolean.toString().toLowerCase() === \"true\") return true;\n        if (string_boolean.toString().toLowerCase() === \"false\") return false;\n        return null;\n    };\n    /**\n     * Utility method for calculating the Start Time based on a threshold duration from now\n     * \n     * @memberof utils\n     * @method getStartTimeForThreshold\n     *\n     * @param {string} duration_type The String value of time duration. E.g: `hours`, `minutes`, `seconds`.\n     * @param {int} duration The duration value of the threshold. Use a positive value for a future time, and \n     *                          a negative value for a past time.\n     *                          E.g: `5` will be 5 hours minutes or seconds in the future, \n     *                              and `-5` will be 5 hours minutes or seconds in the past.\n     * @returns {Date} The Start Time\n     */\n    utils.getStartTimeForThreshold = (duration_type, duration) => {\n        var endDate = new Date();\n        var startDate = new Date(endDate);\n        switch (duration_type) {\n            case \"hours\":\n                startDate.setHours(endDate.getHours() + duration);\n                break;\n            case \"minutes\":\n                startDate.setMinutes(endDate.getMinutes() + duration);\n                break;\n            case \"seconds\":\n                startDate.setSeconds(endDate.getSeconds() + duration);\n                break;\n            default:\n                startDate.setMinutes(endDate.getMinutes() + duration);\n                break;\n        }\n        console.log(\"Start Time: \" + startDate + \" :: UTC: \" + startDate.toISOString());\n        return startDate;\n    };\n    /**\n     * Utility method for returning the local midnight time today\n     * \n     * @memberof utils\n     * @method getLocalMidnight\n     *\n     * @returns {Date} The Date at Midnight today in local time\n     */\n    utils.getLocalMidnight = () => {\n        const dateMidnightLocal = new Date();\n        dateMidnightLocal.setSeconds(0);\n        dateMidnightLocal.setMinutes(0);\n        dateMidnightLocal.setHours(0);\n        console.log(`dateMidnightLocal: ${dateMidnightLocal}, dateMidnightLocal iso: ` + dateMidnightLocal.toISOString());\n        console.log(\"Start Time: \" + startDate + \" :: UTC: \" + startDate.toISOString());\n        return dateMidnightLocal;\n    };\n    /**\n     * Validate the Request URL does not contain the value in the `token` parameter.\n     * \n     * @memberof utils\n     * @method validateRequestURL\n     *\n     * @param {string} token - The value to validate does not exist in the Request URL\n     */\n    utils.validateRequestURL = (token) => {\n        let url = pm.request.url.toString();\n        if (url.toLowerCase().includes(token.toLowerCase())) {\n            throw Error(`Request URL not valid! Please replace the token ${token} with a valid value.`);\n        }\n    };\n    /**\n     * Validate the Request Body does not contain the value in the `token` parameter.\n     * \n     * @memberof utils\n     * @method validateRequestBody\n     *\n     * @param {string} token - The value to validate does not exist in the Request Body\n     */\n    utils.validateRequestBody = (token) => {\n        let body = pm.request.body.toString();\n        if (body.toLowerCase().includes(token.toLowerCase())) {\n            throw Error(`Request Body not valid! Please replace the token ${token} with a valid value.`);\n        }\n    };\n    /**\n     * Validate the GraphQL Request Body does not contain the value in the `token` parameter.\n     * \n     * @memberof utils\n     * @method validateGraphQLRequestBody\n     *\n     * @param {string} token - The value to validate does not exist in the GraphQL Request Body\n     */\n    utils.validateGraphQLRequestBody = (token) => {\n        let query = pm.request.body.graphql.query;\n        if (query.toLowerCase().includes(token.toLowerCase())) {\n            throw Error(`GraphQL Query Body not valid! Please replace the token ${token} with a valid value.`);\n        }\n        let variables = pm.request.body.graphql.variables;\n        if (variables.toLowerCase().includes(token.toLowerCase())) {\n            throw Error(`GraphQL Query Variables not valid! Please replace the token ${token} with a valid value.`);\n        }\n    };\n    /**\n     * Validate the Request does not contain the value in the `token` parameter.\n     * \n     * @memberof utils\n     * @method validateRequestForToken\n     *\n     * @param {string} token - The value to validate does not exist in the Request\n     */\n    utils.validateRequestForToken = (token) => {\n        utils.validateRequestURL(token);\n        if (pm.request.body.graphql) {\n            utils.validateGraphQLRequestBody(token)\n        } else {\n            utils.validateRequestBody(token)\n        }\n    };\n    /**\n     * Validate the Request does not contain the value in the `tokens` parameter.\n     * \n     * @memberof utils\n     * @method validateRequest\n     *\n     * @param {string[]} tokens - The values to validate do not exist in the Request\n     */\n    utils.validateRequest = (tokens) => {\n        if (Array.isArray(tokens)) {\n            for(i in tokens) {\n                utils.validateRequestForToken(tokens[i]);\n            }\n        } else if (typeof tokens === 'string' || tokens instanceof String) {\n            utils.validateRequestForToken(tokens);\n        } else {\n            throw Error(\"Invalid parameter 'tokens'. Please provide an array of string values.\");\n        }\n    };\n    /** \n     * Flatten a JSON Object into a simple key value object\n     * \n     * @memberof utils\n     * @method flattenJSON\n     *\n     * @param {object} json - The JSON Object to flatten\n     */\n     utils.flattenJSON = (json) => {\n        var result = {};\n        function recurse (cur, prop) {\n            if (Object(cur) !== cur) {\n                result[prop] = cur;\n            } else if (Array.isArray(cur)) {\n                for(var i=0, l=cur.length; i<l; i++)\n                    recurse(cur[i], prop ? prop+\".\"+i : \"\"+i);\n                if (l == 0)\n                    result[prop] = [];\n            } else {\n                var isEmpty = true;\n                for (var p in cur) {\n                    isEmpty = false;\n                    recurse(cur[p], prop ? prop+\".\"+p : p);\n                }\n                if (isEmpty)\n                    result[prop] = {};\n            }\n        }\n        recurse(json, \"\");\n        // console.log(\"Inside flattenJSON - result: \" + JSON.stringify(result));\n        return result;\n     };\n    /** \n     * Unflatten a simple key value object into a srtuctured JSON Object\n     * \n     * @memberof utils\n     * @method unflattenJSON\n     *\n     * @param {object} json - The flattened JSON Object to unflatten\n     */\n    utils.unflattenJSON = (json) => {\n        \"use strict\";\n        if (Object(json) !== json || Array.isArray(json))\n            return json;\n        \n        var result = {}, cur, prop, idx, last, temp;\n        \n        for(var p in json) {\n            cur = result, prop = \"\", last = 0;\n            do {\n                idx = p.indexOf(\".\", last);\n                temp = p.substring(last, idx !== -1 ? idx : undefined);\n                cur = cur[prop] || (cur[prop] = (!isNaN(parseInt(temp)) ? [] : {}));\n                prop = temp;\n                last = idx + 1;\n            } while(idx >= 0);\n            cur[prop] = json[p];\n        }\n        return result[\"\"];\n    };\n    /**\n     * Converts a GraphQL Connection object into a simple Array of the relevant Entity at the `node`\n     * \n     * @memberof utils\n     * @method connectionToEntityArray\n     *\n     * @param {object} connection - The GraphQL Connection Object to conver to an Array of the Entity at the `node`\n     */\n    utils.connectionToEntityArray = (connection) => {\n        let entityArray = [];\n        // console.log(\"Inside connectionToEntityArray - connection: \" + JSON.stringify(connection));\n        if (connection.edges) {\n            for (e in connection.edges) {\n                entityArray.push(connection.edges[e].node);\n            }\n        }\n        if (Array.isArray(connection)) {\n            for (e in connection) {\n                entityArray.push(connection[e].node);\n            }\n        }\n        // console.log(\"Inside connectionToEntityArray - result: \" + JSON.stringify(entityArray));\n        return entityArray;\n    };\n     \n    \n    /**\n     * Returns a simple string duration from a `ms` parameter. E.g: 10m 30s or 1h 23m or ~2 days\n     * \n     * @memberof utils\n     * @method getHumanReadableDuration\n     *\n     * @param {integer} ms - The millisecond value to convert to a human readable duration.\n     */\n    utils.getHumanReadableDuration = (ms) => {\n        if (ms < 3600000) {\n            let dur = new Date(ms).toISOString().slice(14, -5);\n            return dur.replace(\":\", \"m \") + \"s\";\n        }\n        if (ms < 86400000) {\n            let dur = new Date(ms).toISOString().slice(11, -8)\n            return dur.replace(\":\", \"h \") + \"m\";\n        }\n        if (ms > 2629743000) {\n            return \"> 1 month\";\n        }\n        let weeks = Math.floor(ms/604800000);\n        let days = Math.floor(ms/86400000);\n        return (days < 14) ? \"~\" + days + \" days\" : \"~\" + weeks + \"weeks\";\n    };\n    /*\n     * Human-readable time  Seconds\n     * 1 hour  3600 seconds\n     * 1 day   86400 seconds\n     * 1 week  604800 seconds\n     * 1 month (30.44 days)    2629743 seconds\n     * 1 year (365.24 days)     31556926 seconds\n     */\n    /**\n     * \n     * \n     */\n    utils.asyncSendRequest = async (request, callback) => {\n        return await utils.sendRequestPromise(request, callback).catch((error) => {throw Error(error)});\n    };\n    /**\n     * \n     * \n     */\n    utils.sendRequestPromise = (request, callback) => {\n        return new Promise((resolve, reject) => {\n                        pm.sendRequest(req,\n                            function(err, res) {\n                                if (err) reject(err);\n                                callback(res);\n                                if (res) resolve(res);\n                            }\n                        );\n                    });\n    };\n    return utils;\n}; loadUtils();"
    },
    {
      "key": "fluent.jetpack.postman.visualiser_templates",
      "value": "/**\n * Returns an instance of the Fluent JetPack Visualiser Templates\n * \n * @fileOverview A set of Utility Methods to support the loading of Visualiser Templates for Postman Responses\n * @version 1.2020.7.0\n * @exports fluent-jetpack-postman/visualiser_templates\n * @namespace visualiser_templates\n * @author: Lesley Dean <lesley.dean@fluentcommerce.com>\n */\nfunction loadVisualiserTemplates() {\n    let visualiser_templates = {};\n    \n    /**\n     * Returns a welcome message to confirm the Visualiser Templates are active.\n     * \n     * @memberof visualiser_templates\n     * @method hello\n     * \n     * @returns {string}\n     */\n    visualiser_templates.hello = () => {\n        console.info(\"Hello from Fluent JetPack Visualiser Templates!\");\n    };\n    \n    visualiser_templates.basicTemplate = () => {\n    \tvar html = `<!DOCTYPE html>\n\t\t\t\t\t<html>\n\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t<meta charset=\"utf-8\">\n\t\t\t\t\t\t\t<meta charset=\"ISO-8859-1\">\n\t\t\t\t\t\t\t<!--<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">-->\n\t\t\t\t\t\t\t<title>{{report.title}}</title>\n\t\t\t\t\t\t\t<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bulma@0.9.0/css/bulma.min.css\">\n\t\t\t\t\t\t\t{{{report.head}}}\n\t\t\t\t\t\t</head>\n\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t<div id=\"fluent-content\">\n\t\t\t\t\t\t\t<section>\n\t\t\t\t\t\t\t\t<div class=\"level m-2\">{{{report.topBar}}}</div>\n\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t<section class=\"hero is-light section\">\n\t\t\t\t\t\t\t\t<div class=\"container\" align=\"center\">\n\t\t\t\t\t\t\t\t\t<h1 class=\"title is-4\">{{{report.title}}}</h1>\n\t\t\t\t\t\t\t\t\t<p class=\"subtitle is-6\">{{{report.subTitle}}}</p>\n\t\t\t\t\t\t\t\t\t<p align=\"center\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"is-size-7\">{{{report.timestamp}}}</span>\n\t\t\t\t\t\t\t\t\t\t<div>{{{report.extraHeaderInfo}}}</div>\n\t\t\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t<section>\n\t\t\t\t\t\t\t\t<div class=\"container px-4\">\n\t\t\t\t\t\t\t\t\t<div class=\"columns is-multiline is-centered\">\n\t\t\t\t\t\t\t\t\t{{#each report.columns}}\n\t\t\t\t\t\t\t\t\t\t<div class=\"column\" id=\"col-{{@index}}\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"panel\">\n\t\t\t\t\t\t\t\t\t\t\t\t<a name=\"{{anchor}}\"><p class=\"panel-heading is-size-6\">{{{title}}}</p></a>\n\t\t\t\t\t\t\t\t                {{#if head}}\n\t\t\t\t\t\t\t\t                <div class=\"panel-block\">\n\t\t\t\t\t\t\t\t                    {{{head}}}\n\t\t\t\t\t\t\t\t                </div>\n\t\t\t\t\t\t\t\t                {{/if}}\n\t\t\t\t\t\t\t\t                <div class=\"panel-block\">\n\t\t\t\t\t\t\t\t                    {{{content}}}\n\t\t\t\t\t\t\t\t                </div>\n\t\t\t\t\t\t\t\t                {{#if foot}}\n\t\t\t\t\t\t\t\t                <div class=\"panel-block\">\n\t\t\t\t\t\t\t\t                    {{{foot}}}\n\t\t\t\t\t\t\t\t                </div>\n\t\t\t\t\t\t\t\t                {{/if}}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t{{/each}}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t{{{report.bodyScripts}}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</body>\n\t\t\t\t\t</html>`;\n\t\tvar basicTemplate = {\n\t\t\ttemplate: html,\n\t\t\tdata: {\n\t\t\t\treport: {\n\t\t\t\t\ttitle: \"\",\n\t\t\t\t\tsubTitle: \"\",\n\t\t\t\t\ttimestamp: \"\",\n\t\t\t\t\tcolumns: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttitle: \"\",\n\t\t\t\t\t\t\tanchor: \"\",\n\t\t\t\t\t\t\tcontent: \"Test Content\",\n\t\t\t\t\t\t\tfoot: \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tbodyScripts: \"\",\n\t\t\t\t\ttopBar: \"\",\n\t\t\t\t\thead: \"\",\n\t\t\t\t\textraHeaderInfo: \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treturn basicTemplate;\n    };\n    \n    visualiser_templates.basicWideTemplate = () => {\n    \tvar html = `<!DOCTYPE html>\n\t\t\t\t\t<html>\n\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t<meta charset=\"utf-8\">\n\t\t\t\t\t\t\t<meta charset=\"ISO-8859-1\">\n\t\t\t\t\t\t\t<!--<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">-->\n\t\t\t\t\t\t\t<title>{{report.title}}</title>\n\t\t\t\t\t\t\t<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bulma@0.9.0/css/bulma.min.css\">\n\t\t\t\t\t\t\t{{{report.head}}}\n\t\t\t\t\t\t</head>\n\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t<div id=\"fluent-content\">\n\t\t\t\t\t\t\t<section>\n\t\t\t\t\t\t\t\t<div class=\"level m-2\">{{{report.topBar}}}</div>\n\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t<section class=\"hero is-light section\">\n\t\t\t\t\t\t\t\t<div class=\"container\" align=\"center\">\n\t\t\t\t\t\t\t\t\t<h1 class=\"title is-4\">{{report.title}}</h1>\n\t\t\t\t\t\t\t\t\t<p class=\"subtitle is-6\">{{report.subTitle}}</p>\n\t\t\t\t\t\t\t\t\t<p align=\"center\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"is-size-7\">{{report.timestamp}}</span>\n\t\t\t\t\t\t\t\t\t\t<div>{{{report.extraHeaderInfo}}}</div>\n\t\t\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t<section>\n\t\t\t\t\t\t\t\t<div class=\"content px-4\">\n\t\t\t\t\t\t\t\t\t<div class=\"panel\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"panel-heading is-clearfix\" style=\"padding: 10px 20px;\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"is-pulled-left\">\n\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"is-size-6\">{{{report.column.title}}}</p>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t{{#if report.column.head}}\n\t\t\t\t\t\t\t                <div class=\"is-pulled-right\">\n\t\t\t\t\t\t\t                    {{{report.column.head}}}\n\t\t\t\t\t\t\t                </div>\n\t\t\t\t\t\t\t                {{/if}}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t                <div class=\"panel-block\">\n\t\t\t\t\t\t                    {{{report.column.content}}}\n\t\t\t\t\t\t                </div>\n\t\t\t\t\t\t                {{#if report.column.foot}}\n\t\t\t\t\t\t                <div class=\"panel-block\">\n\t\t\t\t\t\t                    {{{report.column.foot}}}\n\t\t\t\t\t\t                </div>\n\t\t\t\t\t\t                {{/if}}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t{{{report.bodyScripts}}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</body>\n\t\t\t\t\t</html>`;\n\t\tvar basicWideTemplate = {\n\t\t\ttemplate: html,\n\t\t\tdata: {\n\t\t\t\treport: {\n\t\t\t\t\ttitle: \"\",\n\t\t\t\t\tsubTitle: \"\",\n\t\t\t\t\ttimestamp: \"\",\n\t\t\t\t\tcolumn: {\n\t\t\t\t\t\t\t\ttitle: \"\",\n\t\t\t\t\t\t\t\tcontent: \"Test Content\",\n\t\t\t\t\t\t\t\tfoot: \"\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\tbodyScripts: \"\",\n\t\t\t\t\ttopBar: \"\",\n\t\t\t\t\thead: \"\",\n\t\t\t\t\textraHeaderInfo: \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treturn basicWideTemplate;\n    };\n\tvisualiser_templates.basicWideColumnsTemplate = () => {\n    \tvar html = `<!DOCTYPE html>\n\t\t\t\t\t<html>\n\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t<meta charset=\"utf-8\">\n\t\t\t\t\t\t\t<meta charset=\"ISO-8859-1\">\n\t\t\t\t\t\t\t<!--<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">-->\n\t\t\t\t\t\t\t<title>{{report.title}}</title>\n\t\t\t\t\t\t\t<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bulma@0.9.0/css/bulma.min.css\">\n\t\t\t\t\t\t\t{{{report.head}}}\n\t\t\t\t\t\t</head>\n\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t<div id=\"fluent-content\">\n\t\t\t\t\t\t\t<section>\n\t\t\t\t\t\t\t\t<div class=\"level m-2\">{{{report.topBar}}}</div>\n\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t<section class=\"hero is-light section\">\n\t\t\t\t\t\t\t\t<div class=\"container\" align=\"center\">\n\t\t\t\t\t\t\t\t\t<h1 class=\"title is-4\">{{report.title}}</h1>\n\t\t\t\t\t\t\t\t\t<p class=\"subtitle is-6\">{{report.subTitle}}</p>\n\t\t\t\t\t\t\t\t\t<p align=\"center\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"is-size-7\">{{report.timestamp}}</span>\n\t\t\t\t\t\t\t\t\t\t<div>{{{report.extraHeaderInfo}}}</div>\n\t\t\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t<section>\n\t\t\t\t\t\t\t\t<div class=\"content px-4\">\n\t\t\t\t\t\t\t\t\t<div class=\"columns is-multiline is-centered\">\n\t\t\t\t\t\t\t\t\t{{#each report.columns}}\n\t\t\t\t\t\t\t\t\t\t<div class=\"column is-one-quarter\" id=\"col-{{@index}}\">\n\t\t\t\t\t\t\t\t\t\t\t{{{content}}}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t{{/each}}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t{{{report.bodyScripts}}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</body>\n\t\t\t\t\t</html>`;\n\t\tvar basicWideColumnsTemplate = {\n\t\t\ttemplate: html,\n\t\t\tdata: {\n\t\t\t\treport: {\n\t\t\t\t\ttitle: \"\",\n\t\t\t\t\tsubTitle: \"\",\n\t\t\t\t\ttimestamp: \"\",\n\t\t\t\t\tcolumns: \n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcontent: \"Test Content\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\tbodyScripts: \"\",\n\t\t\t\t\ttopBar: \"\",\n\t\t\t\t\thead: \"\",\n\t\t\t\t\textraHeaderInfo: \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treturn basicWideColumnsTemplate;\n    };\n\tvisualiser_templates.basicOrdersOverviewTemplate = () => {\n\t\tvar html = `<!DOCTYPE html>\n\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t\t<meta charset=\"utf-8\">\n\t\t\t\t\t\t\t\t<meta charset=\"ISO-8859-1\">\n\t\t\t\t\t\t\t\t<title>{{report.title}}</title>\n\t\t\t\t\t\t\t\t<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bulma@0.9.0/css/bulma.min.css\">\n\t\t\t\t\t\t\t\t{{{report.head}}}\n\t\t\t\t\t\t\t</head>\n\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t<div id=\"fluent-content\">\n\t\t\t\t\t\t\t\t<section>\n\t\t\t\t\t\t\t\t\t<div class=\"level m-2\">{{{report.topBar}}}</div>\n\t\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t\t<section class=\"hero is-light section\">\n\t\t\t\t\t\t\t\t\t<div class=\"container\" align=\"center\">\n\t\t\t\t\t\t\t\t\t\t<h1 class=\"title is-4\">{{report.title}}</h1>\n\t\t\t\t\t\t\t\t\t\t<p class=\"subtitle is-6\">{{report.subTitle}}</p>\n\t\t\t\t\t\t\t\t\t\t<p align=\"center\">\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"is-size-7\">{{report.timestamp}}</span>\n\t\t\t\t\t\t\t\t\t\t\t<div>{{{report.extraHeaderInfo}}}</div>\n\t\t\t\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t\t{{#each report.rows}}\n\t\t\t\t\t\t\t\t<section>\n\t\t\t\t\t\t\t\t\t<div class=\"container px-4\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"panel {{bulmaColor}}\">\n\t\t\t\t\t\t\t\t\t\t\t<p class=\"panel-heading is-size-6\">{{title}}</p>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"panel-block level\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{#each values}}\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"level-item has-text-centered\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"heading\">{{key}}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"title\">{{value}}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t{{/each}}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"panel-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"columns\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{{#each children}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"column\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"panel {{bulmaColor}}\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"panel-heading is-size-7\">{{title}}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"panel-block level\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{#each values}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"level-item has-text-centered\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"heading\">{{key}}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"title\">{{value}}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{/each}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{{/each}}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>                        \n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</section>\n\t\t\t\t\t\t\t\t<hr/>\n\t\t\t\t\t\t\t\t{{/each}}\n\t\t\t\t\t\t\t\t{{{report.bodyScripts}}}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t</html>`;\n\t\tvar basicOrderOverviewTemplate = {\n\t\t\ttemplate: html,\n\t\t\tdata: {\n\t\t\t\treport: {\n\t\t\t\t\ttitle: \"\",\n\t\t\t\t\tsubTitle: \"\",\n\t\t\t\t\ttimestamp: \"\",\n\t\t\t\t\trows: [\n\t\t\t\t\t\t{\n\t\t\t\t            title: \"\",\n\t\t\t\t            bulmaColor: \"\",\n\t\t\t\t            values: [{key: \"\", value: \"\"},{key: \"\", value: \"\"}],\n\t\t\t\t            children: [\n\t\t\t\t                {title: \"\", bulmaColor: \"\", values: [{key: \"\", value: \"\"}, {key: \"\", value: \"\"}]},\n\t\t\t\t                {title: \"\", bulmaColor: \"\", values: [{key: \"\", value: \"\"}, {key: \"\", value: \"\"}]},\n\t\t\t\t                {title: \"\", bulmaColor: \"\", values: [{key: \"\", value: \"\"}, {key: \"\", value: \"\"}]}\n\t\t\t\t            ]\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tbodyScripts: \"\",\n\t\t\t\t\ttopBar: \"\",\n\t\t\t\t\thead: \"\",\n\t\t\t\t\textraHeaderInfo: \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treturn basicOrderOverviewTemplate;\n    };\n    return visualiser_templates;\n}\n    // /**\n    //  * Load the Simple Table Template\n    //  * \n    //  * @memberof visualiser_templates\n    //  * @method simpleTable\n    //  * \n    //  */\n    // visualiser_templates.simpleTable = () => {\n    // \t//TODO\n    // };\n    \n    //  *\n    //  * Load the Retailer Overview Dashboard Template\n    //  * \n    //  * @memberof visualiser_templates\n    //  * @method retailerOverviewDashboard\n    //  * \n     \n    // visualiser_templates.retailerOverviewDashboard = () => {\n    // \t//TODO\n    // };\n; loadVisualiserTemplates();"
    },
    {
      "key": "fluent.jetpack.postman.visualiser_utils",
      "value": "/**\n * Returns an instance of the Fluent JetPack Visualiser Utils\n * \n * @fileOverview A set of Utility Methods to support the loading of Visualiser Templates for Postman Responses\n * @version 1.2020.7.0\n * @exports fluent-jetpack-postman/visualiser_utils\n * @namespace visualiser_utils\n * @author: Lesley Dean <lesley.dean@fluentcommerce.com>\n */\nfunction loadVisualiserUtils() {\n\tlet visualiser_utils = {};\n    /**\n     * Returns a welcome message to confirm the Visualiser Utils are active.\n     * \n     * @memberof visualiser_utils\n     * @method hello\n     * \n     * @returns {string} - A welcome message from JetPack\n     */\n    visualiser_utils.hello = () => {\n        console.info(\"Hello from Fluent JetPack Visualiser Utils!\");\n    };\n    /**\n     * Sets the Visualiser for Postman\n     * \n     * @memberof visualiser_utils\n     * @method json2table\n     * \n     * @param {string} template - The Handlebars enabled HTML String to render\n     * @param {object} templateData - The Data provided to the Handlebars enabled Template\n     */\n    visualiser_utils.visualise = (template, templateData) => {\n\t\tpm.visualizer.set(template, templateData);\n    };\n\t/**\n\t * Receives a JSON array and an optional set of css classes to apply to the table which is returned.\n\t * \n     * @memberof visualiser_utils\n     * @method json2table\n     * \n     * @param {array} json - The JSON Array to render to an HTML table\n     * @param {string} classes - A String of CSS classes to apply to the table - e.g.: `\"table is-fullwidth is-striped\"`\n     * @param {string} id - The `id` to assign the table element. This is required is if the Table to CSV Download is enabled\n\t * \n     * @returns {string}\t An HTML Table of the flattened JSON array provided\n     * \n\t */\n\tvisualiser_utils.json2table = (json, classes, id) => {\n\t\tif (!json[0]) {\n\t\t\treturn \"\";\n\t\t}\n\t\tvar cols = (json[0].node) ? Object.keys(utils.flattenJSON(json[0].node)) :  Object.keys(utils.flattenJSON(json[0]));\n\t\tvar headerRow = '';\n\t\tvar bodyRows = '';\n\t\tclasses = classes || '';\n\t\tlet tableId = id ? `id=${id}` : \"\";\n\t\tcols.map(function(col) {\n\t\t\theaderRow += '<th>' + utils.capitalizeFirstLetter(col) + '</th>';\n\t\t});\n\t\tjson.map(function(row) {\n\t\t\trow = (row.node) ? row.node : row;\n\t\t\tflattenedRow = utils.flattenJSON(row);\n\t\t\tbodyRows += '<tr>';\n\t\t\t\n\t\t\t// Loop over object properties and create cells\n\t\t\tcols.map(function(colName) {\n\t\t\t\tbodyRows += '<td style=\"word-wrap: break-all;\">' + flattenedRow[colName] + '</td>';\n\t\t\t});\n\t\t\t\n\t\t\tbodyRows += '</tr>';\n\t\t});\n\t\t// return `<table ${tableId} class=\"${classes}\" style=\"margin-bottom: 10px;\">\n\t\t// \t\t\t<thead><tr>${headerRow}</tr></thead>\n\t\t// \t\t\t<tfoot><tr>${headerRow}</tr></tfoot>\n\t\t// \t\t\t<tbody>${bodyRows}</tbody>\n\t\t// \t\t</table>`;\n\t\treturn `<div class=\"table-container\" style=\"width: 100%;\">\n\t\t\t\t\t<table ${tableId} class=\"${classes}\" style=\"margin-bottom: 10px;\">\n\t\t\t\t\t\t<thead><tr>${headerRow}</tr></thead>\n\t\t\t\t\t\t<tfoot><tr>${headerRow}</tr></tfoot>\n\t\t\t\t\t\t<tbody>${bodyRows}</tbody>\n\t\t\t\t\t</table>\n\t\t\t\t</div>`;\n\t};\n\t/**\n\t * Returns the Javascript functions to support HTML Table to CSV download.\n\t * This should be added to the bottom of the `body` tag in the chosen Visualiser Template.\n\t * \n     * @memberof visualiser_utils\n     * @method table2csvScripts\n     * \n     * @returns {string}\t An HTML Script of the Table to CSV Download functions\n \t */\n\tvisualiser_utils.table2csvScripts = () => {\n\t\tlet script = `<script>\n\t\t\t\t\t\tfunction downloadCSV(csv, filename) {\n\t\t\t\t\t\t    var csvFile;\n\t\t\t\t\t\t    var downloadLink;\n\t\t\t\t\t\t    \n\t\t\t\t\t\t    csvFile = new Blob([csv], {type: \"text/csv\"}); \t\t\t\t// CSV file\n\t\t\t\t\t\t    downloadLink = document.createElement(\"a\"); \t\t\t\t// Download link\n\t\t\t\t\t\t    downloadLink.download = filename; \t\t\t\t\t\t\t// File name\n\t\t\t\t\t\t    downloadLink.href = window.URL.createObjectURL(csvFile); \t// Create a link to the file\n\t\t\t\t\t\t    downloadLink.style.display = \"none\"; \t\t\t\t\t\t// Hide download link\n\t\t\t\t\t\t    document.body.appendChild(downloadLink); \t\t\t\t\t// Add the link to DOM\n\t\t\t\t\t\t    downloadLink.click(); \t\t\t\t\t\t\t\t\t\t// Click download link\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfunction exportTableToCSV(table, filename) {\n\t\t\t\t\t\t    var csv = [];\n\t\t\t\t\t\t    var t = document.querySelector(table);\n\t\t\t\t\t\t    var rows = t.querySelectorAll(\"thead tr, tbody tr\");\n\t\t\t\t\t\t    \n\t\t\t\t\t\t    for (var i = 0; i < rows.length; i++) {\n\t\t\t\t\t\t        var row = [], cols = rows[i].querySelectorAll(\"td, thead th\");\n\t\t\t\t\t\t        \n\t\t\t\t\t\t        for (var j = 0; j < cols.length; j++) {\n\t\t\t\t\t\t        \t// if (i < 4) {\n\t\t\t\t\t\t\t        // \tconsole.log(\"child element count for row\" + i + \"col\" + j + \": \" + cols[j].childElementCount);\n\t\t\t\t\t\t\t        // \tconsole.log(\"child nodes length for row\" + i + \"col\" + j + \": \" + cols[j].childNodes.length);\n\t\t\t\t\t\t\t        // \tconsole.log(\"children length for row\" + i + \"col\" + j + \": \" + cols[j].children.length);\n\t\t\t\t\t\t\t        // \tconsole.log(\"firstElementChild for row\" + i + \"col\" + j + \": \" + cols[j].firstElementChild);\n\t\t\t\t\t\t        \t// }\n\t\t\t\t\t\t        \tif (cols[j].childElementCount === 0) {\n\t\t\t\t\t\t        \t\tif (cols[j].innerText.startsWith(\"[\") || cols[j].innerText.startsWith(\"{\")) {\n\t\t\t\t\t\t\t\t            row.push(JSON.stringify(cols[j].innerText));\n\t\t\t\t\t\t        \t\t} else {\n\t\t\t\t\t\t\t            \trow.push(cols[j].innerText);\t\t\t\t\t\t        \t\t\t\n\t\t\t\t\t\t        \t\t}\n\t\t\t\t\t\t        \t} else {\n\t\t\t\t\t\t\t            row.push(\"Structured Content not currently supported!\");\n\t\t\t\t\t\t        \t}\n\t\t\t\t\t\t        }\n\t\t\t\t\t\t        csv.push(row.join(\",\"));        \n\t\t\t\t\t\t    }\n\t\t\t\t\t\t    // Download CSV file\n\t\t\t\t\t\t    downloadCSV(csv.join(\"\\\\n\"), filename);\n\t\t\t\t\t\t}\n\t\t\t\t\t</script>`;\n\t\treturn script;\n\t}\n\t/**\n\t * Returns a `div` tag containing a button to be associated with an HTML Table for CSV Download\n\t * \n     * @memberof visualiser_utils\n     * @method table2csvButton\n     * \n     * @param {string} tableId - The `id` to assign the table element. This is required is if the Table to CSV Download is enabled\n     * @param {string} filename - The name of the CSV file to be downloaded\n\t * \n     * @returns {string}\t An HTML Div tag with a button to download\n     * \n\t */\n\tvisualiser_utils.table2csvButton = (tableId, filename) => {\n\t\treturn `<div class=\"is-pulled-right\">\n\t\t\t\t\t<button style=\"height: 25px; padding: 0 10px; line-height: 0px;\" onclick=\"exportTableToCSV('#${tableId}', '${filename}')\">Download ${filename}</button>\n\t\t\t\t</div>`;\n\t};\n\t/**\n\t * \n\t * \n\t */\n\tvisualiser_utils.copyToClipboardScripts = () => {\n\t\treturn `<script>\n\t\t\t\t\tfunction copyToClipboard(id) {\n\t\t\t\t\t\tconst copyText = document.getElementById(id).textContent;\n\t\t\t\t\t\tconst textArea = document.createElement('textarea');\n\t\t\t\t\t\ttextArea.textContent = copyText;\n\t\t\t\t\t\tdocument.body.append(textArea);\n\t\t\t\t\t\ttextArea.select();\n\t\t\t\t\t\tdocument.execCommand(\"copy\");\n\t\t\t\t\t}\n\t\t\t\t</script>`;\n\t};\n\t/**\n\t * \n\t * \n\t */\n\tvisualiser_utils.copyToClipboardButton = (elementId) => {\n\t\treturn `<div class=\"is-clearfix is-pulled-right\">\n\t\t\t\t\t<button onclick=\"copyToClipboard('${elementId}')\">Copy to Clipboard</button>\n\t\t\t\t</div>`;\n\t};\n\tvisualiser_utils.keyValuePanel = (panelData) => {\n\t\tlet bodyItems = ``;\n\t\tfor (i in panelData.bodyItems) {\n\t\t\tlet bodyItem = panelData.bodyItems[i];\n\t\t\tbodyItems += `<div class=\"level-item has-text-centered\">\n\t\t\t                    <div>\n\t\t\t\t                    <p class=\"heading\">${bodyItem.key}</p>\n\t\t\t\t                    <p class=\"is-size-5\">${bodyItem.value}</p>\n\t\t\t                    </div>\n\t\t\t                </div>`;\n\t\t}\n\t\t// console.log(\"bodyItems: \" + bodyItems);\n\t\tlet footItems = `<div class=\"panel-block level\">`;\n\t\tif (panelData.footItems) {\n\t\t\tfor (i in panelData.footItems) {\n\t\t\t\tlet footItem = panelData.footItems[i];\n\t\t\t\tfootItems += `<div class=\"level-item has-text-centered\">\n\t\t\t                    <div>\n\t\t\t\t                    <p class=\"heading\">${footItem.key}</p>\n\t\t\t\t                    <p class=\"is-size-6\">${footItem.value}</p>\n\t\t\t                    </div>\n\t\t\t                </div>`;\n\t\t\t}\n\t\t}\n\t\tfootItems += `</div>`;\n\t\t// console.log(\"footItems: \" + footItems);\n\t\tlet html = `<div class=\"panel is-info\">\n\t\t\t            <p class=\"panel-heading is-size-6\">${panelData.title}</p>\n\t\t\t            <div class=\"panel-block level\">\n\t\t\t\t\t\t\t${bodyItems}\n\t\t\t            </div>\n\t\t\t            ${footItems}\n\t\t\t        </div>`;\n\t\t// console.log(\"panel: \" + html);\n\t\t// let keyValuePanelData = {\n\t\t// \ttitle: \"\",\n\t\t// \tbodyItems: [\n\t\t// \t\t{\n\t\t// \t\t\tkey: \"\",\n\t\t// \t\t\tvalue: \"\"\n\t\t// \t\t}\n\t\t// \t],\n\t\t// \tfootItems: [\n\t\t// \t\t{\n\t\t// \t\t\tkey: \"\",\n\t\t// \t\t\tvalue: \"\"\n\t\t// \t\t}\n\t\t// \t]\n\t\t// };\n\t\treturn html;\n\t};\n\t/**\n\t * \n\t * \n\t */\n\tvisualiser_utils.codeHighlightScripts = () => {\n\t\treturn `<script src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js\"></script>\n                <script>hljs.initHighlightingOnLoad();</script>`;\n\t};\n\t/**\n\t * \n\t * \n\t */\n\tvisualiser_utils.codeHighlightStylesheet = () => {\n\t\treturn `<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/github-gist.min.css\">`;\n\t};\n\t/**\n\t * \n\t * \n\t */\n\tvisualiser_utils.formattedCode = (language, stringifiedCode, id) => {\n\t\tlet pre_id = (id) ? id : `${language}code`;\n\t\treturn `<pre id=\"${pre_id}\" style=\"white-space: pre-wrap; tab-size: 2; width: 100%; padding: 0px;\">\n\t\t\t\t\t<code class=\"${language}\" style=\"margin: 0px;\">${stringifiedCode}</code>\n\t\t\t\t</pre>`;\n\t};\n\t/**\n\t * \n\t * \n\t */\n\tvisualiser_utils.findInPageScripts = () => {\n\t\treturn `<script>\n\t\t\t\t\tvar TRange = null;\n\t\t\t\t\tfunction findString(str) {\n\t\t\t\t\t    if (parseInt(navigator.appVersion) < 4) return;\n\t\t\t\t\t    var strFound;\n\t\t\t\t\t    if (window.find) {\n\t\t\t\t\t        // CODE FOR BROWSERS THAT SUPPORT window.find\n\t\t\t\t\t        strFound = self.find(str);\n\t\t\t\t\t        if (strFound && self.getSelection && !self.getSelection().anchorNode) {\n\t\t\t\t\t            strFound = self.find(str)\n\t\t\t\t\t        }\n\t\t\t\t\t        if (!strFound) {\n\t\t\t\t\t            strFound = self.find(str, 0, 1)\n\t\t\t\t\t            while (self.find(str, 0, 1)) continue\n\t\t\t\t\t        }\n\t\t\t\t\t    } else if (navigator.appName.indexOf(\"Microsoft\") != -1) {\n\t\t\t\t\t        // EXPLORER-SPECIFIC CODE        \n\t\t\t\t\t        if (TRange != null) {\n\t\t\t\t\t            TRange.collapse(false)\n\t\t\t\t\t            strFound = TRange.findText(str)\n\t\t\t\t\t            if (strFound) TRange.select()\n\t\t\t\t\t        }\n\t\t\t\t\t        if (TRange == null || strFound == 0) {\n\t\t\t\t\t            TRange = self.document.body.createTextRange()\n\t\t\t\t\t            strFound = TRange.findText(str)\n\t\t\t\t\t            if (strFound) TRange.select()\n\t\t\t\t\t        }\n\t\t\t\t\t    } else if (navigator.appName == \"Opera\") {\n\t\t\t\t\t        alert(\"Opera browsers not supported, sorry...\")\n\t\t\t\t\t        return;\n\t\t\t\t\t    }\n\t\t\t\t\t    if (!strFound) alert(\"String '\" + str + \"' not found!\")\n\t\t\t\t\t        return;\n\t\t\t\t\t};\n\t\t\t\t\tdocument.getElementById('f1').onsubmit = function() {\n\t\t\t\t\t    findString(this.t1.value);\n\t\t\t\t\t    return false;\n\t\t\t\t\t};\n\t\t\t\t</script>`;\n\t};\n\t/**\n\t * \n\t * \n\t */\n\tvisualiser_utils.findInPageStylesheet = () => {\n\t\treturn `<style>\n\t\t\t\t\t#f1 {\n\t\t\t\t\t\tmargin: 0px;\n\t\t\t\t\t}\n\t\t\t\t\t/*#f1 input[type=submit] {\n\t\t\t\t\t    display: none;\n\t\t\t\t\t}*/\n\t\t\t\t\t.t1 {\n\t\t\t\t\t    border: 2px solid orange;\n\t\t\t\t\t    padding: 1px 5px;\n\t\t\t\t\t}\n\t\t\t\t</style>`;\n\t};\n\t\n\t/**\n\t * \n\t * \n\t */\n\tvisualiser_utils.findInPageForm = () => {\n\t\treturn `<form name=\"f1\" id=\"f1\" action=\"\">\n\t\t\t\t    <strong>Search:</strong>\n\t\t\t\t    <input type=\"search\" class=\"t1\" name=\"t1\" value=\"\" alt=\"Type a string to search for and hit Enter\" placeholder=\"Find in page\"/>\n\t\t\t\t    <input type=\"submit\" name=\"b1\" value=\"Find\" />\n\t\t\t\t    <!--<br />\n\t\t\t\t    <small>Type a word/phrase above and press enter to search the page.</small>-->\n\t\t\t\t</form>`;\n\t};\n\t/**\n\t *\n\t *\n\t */\n\tvisualiser_utils.backToTopAnchor = () => {\n\t\treturn `<a name='top'></a>`;\n\t}\n\t/**\n\t *\n\t *\n\t */\n\tvisualiser_utils.backToTopButton = () => {\n\t\treturn `<a href='#top' title='Back to top' id=\"topButton\"\n\t\t\t\t\tstyle='float:right;\n\t\t\t\t\t\t\tposition: fixed;\n\t\t\t\t\t\t\tbottom: 10px;\n\t\t\t\t\t\t\tright: 10px;\n\t\t\t\t\t\t\tcursor: pointer;\n\t\t\t\t\t\t\tpadding: 10px;\n\t\t\t\t\t\t\tbackground-color: #EEE;\n\t\t\t\t\t\t\tcolor: darkgrey;\n\t\t\t\t\t\t\tborder-radius: 5px;'>Back to top</a>`;\n\t}\n\t/**\n\t *\n\t *\n\t */\n\tvisualiser_utils.printStyle = () => {\n\t\treturn `body { font-family: Helvetica; font-size: 9px; } table { border-collapse: collapse; width: 100%; } tbody tr { border-bottom: solid #dbdbdb thin; } tbody tr:nth-child(even) { background-color: #fafafa; } thead tr { border-bottom: solid #dbdbdb; } th, td { padding: 5px; text-align: left; } p { font-weight: bold; font-size: 11px; background-color: #EEE; } button, a#topButton, form { display: none; }`;\n\t};\n\t\n\t/**\n\t *\n\t *\n\t */\n\tvisualiser_utils.printScripts = () => {\n\t\treturn `<script src=\"https://printjs-4de6.kxcdn.com/print.min.js\"></script>`;\n\t};\n\t/**\n\t *\n\t *\n\t */\n\tvisualiser_utils.printButton = (contentId) => {\n\t\treturn `<button onclick=\"printJS({printable: '${contentId}', type: 'html', style: '${visualiser_utils.printStyle()}'});\">Print</button>`;\n\t};\n\t// /**\n\t//  * \n\t//  * \n //     * @memberof visualiser_utils\n\t//  * \n\t//  */\n\t// visualiser_utils.downloadButtonCSV = (json, filename) => {\n\t// \tfilename = filename || \"data-\"+Date.now()+\".csv\";\n\t// \treturn `<a class=\"button is-info\" href=\"\" id=\"downloadbtnCSV\">\n\t// \t\t\t<span class=\"icon\">\n\t// \t\t\t\t<i class=\"fas fa-download\"></i>\n\t// \t\t\t</span>\n\t// \t\t\t<span>Download ${filename} File</span>\n\t// \t\t\t</a>\n\t// \t\t\t<script src=\"https://cdn.jsdelivr.net/npm/json2csv@4.2.1\"></script>\n\t// \t\t\t<script>\n\t// \t\t\t\tvar csv = json2csv.parse(\"{{json}}\", {quote: \"\"});\n\t// \t\t\t  \tlet file = new Blob([csv], {type: 'text/csv'});\n\t// \t\t\t\tdownloadbtn.href = URL.createObjectURL(file);\n\t// \t\t\t\tdownloadbtn.download = ${filename};\n\t// \t\t\t</script>`;\n\t// };\n\t//\t/**\n\t//\t * \n\t//\t * \n\t//     * @memberof visualiser_utils\n\t//\t * \n\t//\t */\n\t//\tvisualiser_utils.downloadButtonJSON = () => {\n\t//\n\t//\t};\n\treturn visualiser_utils;\n}; loadVisualiserUtils();"
    },
    {
      "key": "fluent.jetpack.postman.test_utils",
      "value": "/**\n * Returns an instance of the Fluent JetPack Postman Test Utility\n * \n * @version 1.2020.7.0\n * @exports fluent-jetpack-postman/test_utils\n * @namespace test_utils\n * @author: Lesley Dean <lesley.dean@fluentcommerce.com>\n */\nfunction loadTestUtils() {\n    let testutils = {};\n    /**\n     * Returns a welcome message to confirm the Test Utils are active.\n     * \n     * @memberof test_utils\n     * @method hello\n     */\n    testutils.hello = () => {\n        console.info(\"Hello from Fluent JetPack LaunchPad Test Utils!\");\n    };\n    /**\n     * Checks that the response code is `200`, and that the response body does not contain an `error`\n     */\n    testutils.standardTests = () => {\n        \n        pm.test(\"Status code is 200\", function () {\n            pm.response.to.have.status(200);\n        });\n        \n        pm.test(\"Response is okay to process\", function () {\n            pm.response.to.not.be.error;\n            pm.response.to.not.have.jsonBody(\"error\");\n        });\n    }\n    testutils.validateField = (field_name) => {\n    \t// TODO\n    }\n    return testutils;\n}\n; loadTestUtils();"
    }
  ]
}