{"database": "fishbowl_archive", "table": "biscript", "is_view": false, "human_description_en": "", "rows": [[1, "_binary \u0001", "<html lang=\"en\">\n\n<head>\n    {% Template Default_Header %}\n</head>\n\n<body>\n    <div class=\"overflowHidden\" style=\"height: 90vh; width: 100%;\">\n        <div id=\"headerContainer\">\n            <h1 id=\"title\"></h1>\n            <h2 id=\"subTitle\"></h2>\n            <h3 id=\"description\"></h3>\n        </div>\n        <div id=\"chartContainer\">\n            <canvas id=\"myChart\"></canvas>\n        </div>\n    </div>\n    \n    <script>\n    {% Script Util %}\n    {% Script MTD_Chart %}\n    {% Script Print %}\n    {% Script Show_Header %}\n    </script>\n    \n</body>\n\n</html>", "2024-05-15 08:55:40.400000", "Compares current fulfilled month to date revenue against last year", "MTD Chart", "", 10, 3, "mtd-chart", 1], [2, "_binary \u0001", "const today = new Date();\r\n\r\nvar canvas = document.querySelector('canvas');\r\n\r\nfunction createYearQuery(subtractYear) {\r\n    let mm = (today.getMonth() + 1).toString().padStart(2, '0'); // January is 0!\r\n    let timestamp = (today.getFullYear() - subtractYear) + '-' + mm + '-01 00:00:00';\r\n    \r\n    return \"SELECT DAY(PostSo.postDate) AS PostedDate, SUM(PostSoItem.totalPrice) AS TotalPrice \"\r\n        + \"FROM PostSoItem \"\r\n        + \"JOIN PostSo ON PostSo.id = PostSoItem.postSoId \"\r\n        + \"JOIN SoItem ON PostSoItem.soItemId = SoItem.id AND SoItem.typeId <> 40 AND SoItem.statusID = 50 \"\r\n        + \"WHERE postDate >= '\" + timestamp + \"' \"\r\n        + \"AND postDate < DATE_ADD('\" + timestamp + \"', INTERVAL 1 MONTH) \"\r\n        + \"GROUP BY CAST(PostSo.postDate AS DATE)\";\r\n}\r\n\r\n\r\n\r\nfunction createData(query) {\r\n    const result = runQuery(query);\r\n    return JSON.parse(result);\r\n}\r\nfunction createDataset(label, data, backgroundColor, borderColor) {\r\n    return {\r\n        label: label,\r\n        fill: true,\r\n        data: data,\r\n        backgroundColor: backgroundColor,\r\n        borderColor: borderColor,\r\n        borderWidth: 2,\r\n        pointRadius: 3,\r\n        pointHoverRadius: 5,\r\n        pointHitRadius: 7,\r\n        lineTension: 0\r\n    };\r\n}\r\n\r\nconst data = [];\r\ndata.push(createData(createYearQuery(1)));\r\ndata.push(createData(createYearQuery(0)));\r\nconsole.log(data);\r\n\r\nlet runningTotal = 0;\r\nconst monthData = [];\r\nconst labels = [];\r\nfor (let year = 0; year < data.length; year++) {\r\n    if(data[year].length != 0){\r\n        data[year] = data[year].reduce(\r\n            (obj, day) => {\r\n                obj[day.posteddate] = day.totalprice;\r\n                return obj;\r\n            }, {});\r\n            \r\n        runningTotal = 0;\r\n        let mData = [];\r\n        let yearOffset = 1\r\n        if (year == 1) {yearOffset = 0}\r\n        for (let day = 1; day <= new Date((today.getFullYear() - yearOffset), today.getMonth() + 1, 0).getDate(); day++) {\r\n            if (labels.length < moment().daysInMonth()) {\r\n                labels.push(day);\r\n            }\r\n    \r\n            if (year === data.length - 1 && day > today.getDate()) {\r\n                continue;\r\n            }\r\n    \r\n            runningTotal += data[year][day] || 0;\r\n            mData.push(runningTotal);\r\n        }\r\n        monthData.push(mData);\r\n    }\r\n}\r\n\r\nconst chartData = [];\r\nconst currentYearColor = '$COLOR{Current_Year|#33D566}';\r\nconst previousYearColor = '$COLOR{Previous_Year|#4682b4}';\r\n\r\nif (monthData.length == 1) {\r\n    chartData.push(createDataset(today.getFullYear(), monthData[0], UTIL.convertHex(currentYearColor, 50), currentYearColor));\r\n    chartData.push(createDataset(today.getFullYear() - 1, monthData[1], UTIL.convertHex(previousYearColor, 50), previousYearColor));\r\n} else {\r\n    chartData.push(createDataset(today.getFullYear(), monthData[1], UTIL.convertHex(currentYearColor, 50), currentYearColor));\r\n    chartData.push(createDataset(today.getFullYear() - 1, monthData[0], UTIL.convertHex(previousYearColor, 50), previousYearColor));\r\n}\r\n\r\nconst options = {\r\n        legend: {\r\n            position: 'right'\r\n        },\r\n        scales: {\r\n            yAxes: [{\r\n                ticks: {\r\n                    beginAtZero: true,\r\n                    callback: function (value, values) {\r\n                        return UTIL.dollarify(value, 0);\r\n                    }\r\n                }\r\n            }],\r\n        },\r\n        tooltips: {\r\n            callbacks: {\r\n                label: function (tooltipItem, data) {\r\n                    return UTIL.dollarify(tooltipItem.yLabel);\r\n                },\r\n                title: (tooltipItem) => {\r\n                    return moment().format('MMMM') + ' ' + tooltipItem[0].xLabel;\r\n                 }\r\n            }\r\n        },\r\n    responsive: true,\r\n    maintainAspectRatio: false,\r\n    plugins: {\r\n        datalabels: {\r\n            display: false\r\n        }\r\n    }\r\n};\r\nconst ctx = document.getElementById('myChart');\r\nnew Chart(ctx, {\r\n    type: 'line',\r\n    data: {\r\n        labels: labels,\r\n        datasets: chartData\r\n    },\r\n    options: options\r\n});\r\n\r\ndocument.getElementById(\"title\").innerHTML = 'Revenue ' + moment().format('MMMM') + ' ' + today.getFullYear();\r\ndocument.getElementById(\"subTitle\").innerHTML = 'MTD - ' + UTIL.dollarify(runningTotal);\r\ndocument.getElementById(\"description\").innerHTML = '<Description>';\r\n\r\n\r\n", "2024-05-15 08:55:40.430000", "Query and logic for the MTD Chart page", "MTD Chart", "", 20, 3, "mtd-chart", 0], [3, "_binary \u0001", "<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\r\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js\"></script>\r\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.21.0/moment.min.js\"></script>\r\n<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>\r\n<link href=\"https://fonts.googleapis.com/css?family=Roboto\" rel=\"stylesheet\">\r\n<script src=\"https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels\"></script>\r\n<style type=\"text/css\"> {% Style Default_Style %} </style>", "2023-01-05 17:28:06.927000", "Default header that includes common library dependencies", "Default Header", "", 40, 2, "fb-gadget-header", 0], [4, "_binary \u0001", "const UTIL = {\r\n    \"convertHex\": function(hex,opacity) {\r\n        hex = hex.replace('#','');\r\n        r = parseInt(hex.substring(0,2), 16);\r\n        g = parseInt(hex.substring(2,4), 16);\r\n        b = parseInt(hex.substring(4,6), 16);\r\n\r\n        const result = 'rgba('+r+','+g+','+b+','+opacity/100+')';\r\n        return result;\r\n    },\r\n    \r\n    \"dollarify\": function (amount, decimalCount = 2, decimal = \".\", thousands = \",\") {\r\n        decimalCount = Math.abs(decimalCount);\r\n        decimalCount = isNaN(decimalCount) ? 2 : decimalCount;\r\n    \r\n        const negativeSign = amount < 0 ? \"-\" : \"\";\r\n    \r\n        let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();\r\n        let j = (i.length > 3) ? i.length % 3 : 0;\r\n    \r\n        return '$' + negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\\d{3})(?=\\d)/g, \"$1\" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : \"\");\r\n    },\r\n    \r\n    \"uomify\" : function(qty, uom){\r\n        return qty.toString() + \" \" + uom;\r\n    },\r\n    \r\n    \"convertDate\": function(date, isFromDate) {\r\n        const parsed = new Date(Date.parse(date));\r\n        if (isFromDate) {\r\n            return moment(parsed.setDate(parsed.getDate() + 1)).format('MM/DD/YYYY');\r\n        }\r\n        return moment(parsed.setDate(parsed.getDate())).format('MM/DD/YYYY');\r\n    },\r\n\r\n    \"makeTable\": function (query, headersArray, dontShow = []) {\r\n        var tr = \"<tr style=\\\"border-bottom:2pt solid black;\\\" >\";\r\n\r\n        // SET COLUMN HEADERS\r\n        for (var h = 0; h < headersArray.length; h++) {\r\n            tr += \"<td>\" + headersArray[h] + \"</td>\";\r\n        }\r\n\r\n        //ADD ROW DATA FROM QUERY\r\n        for (var i = 0; i < query.length; i++) {\r\n            // ADD NEW ROW\r\n            tr += \"<tr>\";\r\n            // PRINT COLUMN DATA FOR THIS ROW\r\n            for (var j in query[i]) {\r\n                // CHECK TO SEE IF IT IS IN DONT SHOW LIST\r\n                if (dontShow.includes(j)) {\r\n                    continue;\r\n                }\r\n                else {\r\n                    if (query[i].hasOwnProperty(j)) {\r\n                        tr += \"<td>\" + query[i][j] + \"</td>\";\r\n                    }\r\n                }\r\n            }\r\n            tr += \"</tr>\"\r\n        }\r\n        return tr;\r\n    },\r\n    \r\n    \"unflatten\" :  function(data) {\r\n        \"use strict\";\r\n        if (Object(data) !== data || Array.isArray(data)) {\r\n            return data;\r\n        }\r\n        \r\n        var result = {}, cur, prop, idx, last, temp;\r\n        for(var p in data) {\r\n            cur = result, prop = \"\", last = 0;\r\n            do {\r\n                idx = p.indexOf(\".\", last);\r\n                temp = p.substring(last, idx !== -1 ? idx : undefined);\r\n                cur = cur[prop] || (cur[prop] = (!isNaN(parseInt(temp)) ? [] : {}));\r\n                prop = temp;\r\n                last = idx + 1;\r\n            } while(idx >= 0);\r\n            cur[prop] = data[p];\r\n        }\r\n        return result[\"\"];\r\n    },\r\n    \r\n    \"flatten\" : function(data) {\r\n        var result = {};\r\n        function recurse (cur, prop) {\r\n            if (Object(cur) !== cur) {\r\n                result[prop] = cur;\r\n            } else if (Array.isArray(cur)) {\r\n                for(var i=0, l=cur.length; i<l; i++) {\r\n                    recurse(cur[i], prop ? prop+\".\"+i : \"\"+i);\r\n                }\r\n                if (l == 0) {\r\n                    result[prop] = [];\r\n                }\r\n            } else {\r\n                var isEmpty = true;\r\n                for (var p in cur) {\r\n                    isEmpty = false;\r\n                    recurse(cur[p], prop ? prop+\".\"+p : p);\r\n                }\r\n                if (isEmpty) {\r\n                    result[prop] = {};\r\n                }\r\n            }\r\n        }\r\n    },\r\n    \r\n    \"objContains\" : function (obj, key) {\r\n        var x;\r\n        for (x in obj) {\r\n            if (obj.hasOwnProperty(x) && x === key) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n}", "2023-01-05 17:28:06.927000", "Helper JavaScript functions for manipulating data", "Util", "", 20, 3, "fb-util", 0], [5, "_binary \u0001", "var mediaQueryList = window.matchMedia('print');\r\nmediaQueryList.onchange= function(mql) {\r\n  if(mql.matches) {\r\n    beforePrintHandler();\r\n  }\r\n};\r\n\r\nfunction beforePrintHandler() {\r\n  for (var id in Chart.instances) {\r\n    Chart.instances[id].resize();\r\n  }\r\n}", "2023-01-05 17:28:06.927000", "Allows the charts to fit the page when printing", "Print", "", 20, 1, "fb-printing", 0], [6, "_binary \u0001", "{% Style Print_Landscape %}\r\n\r\nbody {\r\n    font-family: Roboto;\r\n    color: #888;\r\n    margin: 0;\r\n    padding: 0;\r\n}\r\n\r\n.overflowHidden {\r\n    overflow: hidden;\r\n}\r\n\r\n#chartContainer {\r\n    position: relative; \r\n    height: 85%; \r\n    width: 100vw;\r\n    padding-top: 20px;\r\n}\r\n\r\n@media (max-height: 450px){\r\n    #chartContainer {\r\n        height: 75%; \r\n    }\r\n}\r\n\r\n@media (max-height: 300px){\r\n    #chartContainer {\r\n        height: 70%; \r\n    }\r\n}\r\n\r\nh1, h2, h3 {\r\n    margin: 2px;\r\n    font-size: 16px;\r\n}\r\n\r\n#title {\r\n    font-size: 24px;\r\n    color: #666;\r\n}\r\n\r\n#headerContainer {\r\n    text-align: center;\r\n}\r\n\r\n#button {\r\n    background-color: #449D44;\r\n    border-radius: 10%;\r\n    border: 1px solid green;\r\n    color: white;\r\n    text-align: center;\r\n    text-decoration: none;\r\n    display: inline-block;\r\n    font-size: 14px;\r\n    visibility: hidden;\r\n    position: absolute;\r\n    top: 5;\r\n    left: 5;\r\n    z-index: 1;\r\n}", "2023-01-05 17:28:06.943000", "Default style settings for the pages", "Default Style", "", 30, 2, "fb-template-style", 0], [7, "_binary \u0001", "const COLORS = {\r\n    \"blue\": \"rgb(0,0,255)\",\r\n    \"red\": \"rgb(255,0,0)\",\r\n    \"green\": \"rgb(0,255,0)\",\r\n    \"colors\": [\"#673AB7\", \"#2196F3\", \"#E91E63\", \"#F44336\", \"#009688\", \"#4CAF50\", \"#FFC107\", \"#795548\"],\r\n    \"get\": function(num) {\r\n        const full = [];\r\n        const half = [];\r\n        for (let i = 0; i < num; i++) {\r\n            full.push(UTIL.convertHex(this.colors[i%this.colors.length], 100));\r\n            half.push(UTIL.convertHex(this.colors[i%this.colors.length], 50));\r\n        }\r\n        return {\r\n            \"fullAlpha\": full,\r\n            \"halfAlpha\": half\r\n        };\r\n    }\r\n\r\n};", "2023-01-05 17:28:06.943000", "Set of default colors", "Colors", "", 20, 1, "fb-colors", 0], [8, "_binary \u0001", "/**\r\n * [Chart.PieceLabel.js]{@link https://github.com/emn178/Chart.PieceLabel.js}\r\n *\r\n * @version 0.9.0\r\n * @author Chen, Yi-Cyuan [emn178@gmail.com]\r\n * @copyright Chen, Yi-Cyuan 2017\r\n * @license MIT\r\n */\r\n(function(){function c(){this.drawDataset=this.drawDataset.bind(this)}\"undefined\"===typeof Chart?console.warn(\"Can not find Chart object.\"):(c.prototype.beforeDatasetsUpdate=function(a){if(this.parseOptions(a)&&\"outside\"===this.position){var b=1.5*this.fontSize+2;a.chartArea.top+=b;a.chartArea.bottom-=b}},c.prototype.afterDatasetsDraw=function(a){this.parseOptions(a)&&(this.labelBounds=[],a.config.data.datasets.forEach(this.drawDataset))},c.prototype.drawDataset=function(a){for(var b=this.ctx,p=this.chartInstance,\r\nl=a._meta[Object.keys(a._meta)[0]],h=0,f=0;f<l.data.length;f++){var g=l.data[f],d=g._view;if(0!==d.circumference||this.showZero){switch(this.render){case \"value\":var e=a.data[f];this.format&&(e=this.format(e));e=e.toString();break;case \"label\":e=p.config.data.labels[f];break;case \"image\":e=this.images[f]?this.loadImage(this.images[f]):\"\";break;default:var q=d.circumference/this.options.circumference*100;q=parseFloat(q.toFixed(this.precision));this.showActualPercentages||(h+=q,100<h&&(q-=h-100,q=parseFloat(q.toFixed(this.precision))));\r\ne=q+\"%\"}\"function\"===typeof this.render&&(e=this.render({label:p.config.data.labels[f],value:a.data[f],percentage:q,dataset:a,index:f}),\"object\"===typeof e&&(e=this.loadImage(e)));if(!e)break;b.save();b.beginPath();b.font=Chart.helpers.fontString(this.fontSize,this.fontStyle,this.fontFamily);if(\"outside\"===this.position||\"border\"===this.position&&\"pie\"===p.config.type){var k=d.outerRadius/2;var c,m=this.fontSize+2;var n=d.startAngle+(d.endAngle-d.startAngle)/2;\"border\"===this.position?c=(d.outerRadius-\r\nk)/2+k:\"outside\"===this.position&&(c=d.outerRadius-k+k+m);n={x:d.x+Math.cos(n)*c,y:d.y+Math.sin(n)*c};if(\"outside\"===this.position){n.x=n.x<d.x?n.x-m:n.x+m;var r=d.outerRadius+m}}else k=d.innerRadius,n=g.tooltipPosition();m=this.fontColor;\"function\"===typeof m?m=m({label:p.config.data.labels[f],value:a.data[f],percentage:q,text:e,backgroundColor:a.backgroundColor[f],dataset:a,index:f}):\"string\"!==typeof m&&(m=m[f]||this.options.defaultFontColor);if(this.arc)r||(r=(k+d.outerRadius)/2),b.fillStyle=\r\nm,b.textBaseline=\"middle\",this.drawArcText(e,r,d,this.overlap);else{k=this.measureText(e);d=n.x-k.width/2;k=n.x+k.width/2;var t=n.y-this.fontSize/2,u=n.y+this.fontSize/2;(this.overlap||(\"outside\"===this.position?this.checkTextBound(d,k,t,u):g.inRange(d,t)&&g.inRange(d,u)&&g.inRange(k,t)&&g.inRange(k,u)))&&this.fillText(e,n,m)}b.restore()}}},c.prototype.parseOptions=function(a){var b=a.options.pieceLabel;return b?(this.chartInstance=a,this.ctx=a.chart.ctx,this.options=a.config.options,this.render=\r\nb.render||b.mode,this.position=b.position||\"default\",this.arc=b.arc,this.format=b.format,this.precision=b.precision||0,this.fontSize=b.fontSize||this.options.defaultFontSize,this.fontColor=b.fontColor||this.options.defaultFontColor,this.fontStyle=b.fontStyle||this.options.defaultFontStyle,this.fontFamily=b.fontFamily||this.options.defaultFontFamily,this.hasTooltip=a.tooltip._active&&a.tooltip._active.length,this.showZero=b.showZero,this.overlap=b.overlap,this.images=b.images||[],this.showActualPercentages=\r\nb.showActualPercentages||!1,!0):!1},c.prototype.checkTextBound=function(a,b,p,l){for(var h=this.labelBounds,f=0;f<h.length;++f){for(var g=h[f],d=[[a,p],[a,l],[b,p],[b,l]],e=0;e<d.length;++e){var c=d[e][0],k=d[e][1];if(c>=g.left&&c<=g.right&&k>=g.top&&k<=g.bottom)return!1}d=[[g.left,g.top],[g.left,g.bottom],[g.right,g.top],[g.right,g.bottom]];for(e=0;e<d.length;++e)if(c=d[e][0],k=d[e][1],c>=a&&c<=b&&k>=p&&k<=l)return!1}h.push({left:a,right:b,top:p,bottom:l});return!0},c.prototype.measureText=function(a){return\"object\"===\r\ntypeof a?{width:a.width,height:a.height}:this.ctx.measureText(a)},c.prototype.fillText=function(a,b,p){var c=this.ctx;\"object\"===typeof a?c.drawImage(a,b.x-a.width/2,b.y-a.height/2,a.width,a.height):(c.fillStyle=p,c.textBaseline=\"top\",c.textAlign=\"center\",c.fillText(a,b.x,b.y-this.fontSize/2))},c.prototype.loadImage=function(a){var b=new Image;b.src=a.src;b.width=a.width;b.height=a.height;return b},c.prototype.drawArcText=function(a,b,c,l){var h=this.ctx,f=c.x,g=c.y,d=c.startAngle;c=c.endAngle;h.save();\r\nh.translate(f,g);g=c-d;d+=Math.PI/2;c+=Math.PI/2;var e=d;f=this.measureText(a);d+=(c-(f.width/b+d))/2;if(l||!(c-d>g))if(\"string\"===typeof a)for(h.rotate(d),l=0;l<a.length;l++)d=a.charAt(l),f=h.measureText(d),h.save(),h.translate(0,-1*b),h.fillText(d,0,0),h.restore(),h.rotate(f.width/b);else h.rotate((e+c)/2),h.translate(0,-1*b),this.fillText(a,{x:0,y:0});h.restore()},Chart.pluginService.register({beforeInit:function(a){a.pieceLabel=new c},beforeDatasetsUpdate:function(a){a.pieceLabel.beforeDatasetsUpdate(a)},\r\nafterDatasetsDraw:function(a){a.pieceLabel.afterDatasetsDraw(a)}}))})();", "2023-01-05 17:28:06.943000", "Chart js plugin to show labels on the chart", "Chart Piece Label", "", 20, 1, "chart-piece-label", 0], [9, "_binary \u0001", "<html lang=\"en\">\r\n\r\n<head>\r\n    {% Template Default_Header %}\r\n</head>\r\n\r\n<body>\r\n    <div style=\"position: relative; width: 100%; height: 90%;\">\r\n    <button id=\"button\">back</button>   \r\n        <div id=\"headerContainer\">\r\n            <h1 id=\"title\"></h1>\r\n            <h2 id=\"subTitle\"></h2>\r\n            <h3 id=\"description\"></h3>\r\n        </div>\r\n        <div id=\"regions_div\" style=\"position: relative; width: 100%; height: 90%; padding-top: 20px;\"></div>\r\n    </div>\r\n\r\n    <script>\r\n    {% Script Util %}\r\n    {% Script Colors %}\r\n    {% Script Chart_Piece_Label %}\r\n    {% Script Sales_By_Region %}\r\n    {% Script Print %}\r\n    {% Script Show_Header %}\r\n    </script>\r\n    \r\n</body>\r\n\r\n</html>", "2023-01-05 17:28:06.943000", "Map that displays revenue by region", "Sales By Region", "Default Location Syntax:\nUnited States: US\nCalifornia: US-CA\nUtah: US-UT\nAustralia: AU\nNew South Wales, AU: AU-NSW", 10, 3, "sales-by-region", 1], [10, "_binary \u0001", "google.charts.load('current', {\r\n  'packages': ['geochart'],\r\n  'mapsApiKey': 'AIzaSyBZsbr4RQBre8LIOeEN9P-qlmiKGSi95aU'\r\n});\r\n\r\nconst dateRange = $RANGE{Date_Range|This year-to-date};\r\nlet defaultDrillDown = {\r\n    region: \"$TEXT{Default_Location|Global}\"\r\n};\r\nlet dateStr = UTIL.convertDate(dateRange.fromDate, true) + \" - \" + UTIL.convertDate(dateRange.toDate, false);\r\nif (moment(dateRange.fromDate).isSame('1000-01-01', 'year') && moment(dateRange.toDate).isSame('3000-01-01', 'year')) {\r\n  dateStr = 'All';\r\n}\r\n\r\nconst VIEW = {\r\n  world: \"world\",\r\n  country: \"country\",\r\n  province: \"province\"\r\n};\r\n\r\nlet currentView = VIEW.world;\r\nlet previousCountry;\r\ngoogle.charts.setOnLoadCallback(drawWorldMap);\r\n\r\nconst btnBack = document.getElementById('button');\r\nconst subTitleHTML = document.getElementById('subTitle');\r\nconst titleHTML = document.getElementById('title');\r\nconst descriptionHTML = document.getElementById('description');\r\n\r\nbtnBack.addEventListener(\"click\", btnBackEvent);\r\nlet chart;\r\n\r\nlet currentData = {};\r\n\r\nlet subTitle = 'Global';\r\n\r\nlet worldData;\r\n\r\nlet countryData;\r\nlet countryOptions = {\r\n  legend: {\r\n    textStyle: {\r\n      fontSize: 16\r\n    },\r\n    numberFormat: '\u00c2\u00a4#,##0.00'\r\n  },\r\n  resolution: \"provinces\",\r\n  keepAspectRatio: true,\r\n  width: '100%',\r\n  height: '100%'\r\n};\r\n\r\nfunction getWorldData() {\r\n  let worldFbData = JSON.parse(runQuery(\"SELECT SUM(postSoItem.totalPrice) AS totalPrice, abbreviation FROM postSoItem \" +\r\n    \"JOIN soItem ON postSoItem.soItemId = soItem.id \" +\r\n    \"JOIN so ON so.id = soItem.soId AND soItem.statusID = 50 AND soItem.typeId <> 40 \" +\r\n    \"JOIN CountryConst ON so.billToCountryId = CountryConst.id \" +\r\n    \"JOIN postso ON postso.id = postsoitem.postsoid \" +\r\n    \"WHERE postSoItem.totalPrice > 0 AND postSo.postDate >= '\" + dateRange.fromDate + \"' AND postSo.postDate <= '\" + dateRange.toDate + \"' \" +\r\n    \"GROUP BY CountryConst.id\"));\r\n\r\n  let worldData = [\r\n    ['Country', 'Revenue', {\r\n      type: 'string',\r\n      role: 'tooltip'\r\n    }]\r\n  ];\r\n  for (let i = 0; i < worldFbData.length; i++) {\r\n    worldData.push([worldFbData[i].abbreviation, worldFbData[i].totalprice, 'Revenue: ' + UTIL.dollarify(worldFbData[i].totalprice)]);\r\n  }\r\n\r\n  return worldData;\r\n}\r\n\r\n// Solid color fill for US, CA, and AU\r\nfunction getSolidProvincesData(country) {\r\n  let USCAdata = JSON.parse(runQuery(\"SELECT SUM(postSoItem.totalPrice) AS totalPrice, code AS state, billToCity AS city FROM postSoItem \" +\r\n    \"JOIN soItem ON postSoItem.soItemId = soItem.id \" +\r\n    \"JOIN so ON so.Id = soItem.soId AND soItem.statusId = 50 AND soItem.typeId <> 40 \" +\r\n    \"LEFT JOIN StateConst ON so.billToStateId = StateConst.id \" +\r\n    \"JOIN CountryConst ON so.billToCountryId = CountryConst.id AND CountryConst.abbreviation = '\" + country + \"' \" +\r\n    \"JOIN postso ON postso.soId = so.id \" +\r\n    \"WHERE postSoItem.totalPrice > 0 AND postSo.postDate >= '\" + dateRange.fromDate + \"' AND postSo.postDate <= '\" + dateRange.toDate + \"' \" +\r\n    \"GROUP BY state\"));\r\n\r\n  let tableData = [\r\n    [\"State\", \"Revenue\", {\r\n      type: 'string',\r\n      role: 'tooltip'\r\n    }]\r\n  ];\r\n\r\n  for (let i = 0; i < USCAdata.length; i++) {\r\n    let region = country + \"-\" + USCAdata[i].state;\r\n    tableData.push([region, USCAdata[i].totalprice, 'Revenue: ' + UTIL.dollarify(USCAdata[i].totalprice)]);\r\n  }\r\n\r\n  return tableData;\r\n}\r\n\r\nfunction getCountryData(country) {\r\n  let countryFbData = JSON.parse(runQuery(\"SELECT SUM(postSoItem.totalPrice) AS totalPrice, code AS state, billToCity AS city FROM postSoItem \" +\r\n    \"JOIN soItem ON postSoItem.soItemId = soItem.id \" +\r\n    \"JOIN so ON so.Id = soItem.soId AND soItem.statusId = 50 AND soItem.typeId <> 40 \" +\r\n    \"LEFT JOIN StateConst ON so.billToStateId = StateConst.id \" +\r\n    \"JOIN CountryConst ON so.billToCountryId = CountryConst.id AND CountryConst.abbreviation = '\" + country + \"' \" +\r\n    \"JOIN postso ON postso.soId = so.id \" +\r\n    \"WHERE postSoItem.totalPrice > 0 AND postSo.postDate >= '\" + dateRange.fromDate + \"' AND postSo.postDate <= '\" + dateRange.toDate + \"' \" +\r\n    \"GROUP BY city\"));\r\n\r\n  let tableData = [\r\n    [\"City\", \"Revenue\", {\r\n      type: 'string',\r\n      role: 'tooltip'\r\n    }]\r\n  ];\r\n\r\n  for (let i = 0; i < countryFbData.length; i++) {\r\n    tableData.push([countryFbData[i].city, countryFbData[i].totalprice, 'Revenue: ' + UTIL.dollarify(countryFbData[i].totalprice)]);\r\n  }\r\n\r\n  return tableData;\r\n}\r\n\r\nfunction getProvinceData(country, province) {\r\n  let provinceData = JSON.parse(runQuery(\"SELECT SUM(postSoItem.totalPrice) AS totalPrice, code AS state, billToCity AS city FROM postSoItem \" +\r\n    \"JOIN soItem ON postSoItem.soItemId = soItem.id \" +\r\n    \"JOIN so ON so.Id = soItem.soId AND soItem.statusId = 50 AND soItem.typeId <> 40 \" +\r\n    \"LEFT JOIN StateConst ON so.billToStateId = StateConst.id \" +\r\n    \"JOIN CountryConst ON so.billToCountryId = CountryConst.id AND CountryConst.abbreviation = '\" + country + \"' \" +\r\n    \"JOIN postso ON postso.soId = so.id \" +\r\n    \"WHERE postSoItem.totalPrice > 0 AND postSo.postDate >= '\" + dateRange.fromDate + \"' AND postSo.postDate <= '\" + dateRange.toDate + \"' \" +\r\n    \"AND CODE = '\" + province + \"' \" +\r\n    \"GROUP BY city\"));\r\n\r\n  let tableData = [\r\n    [\"City\", \"Revenue\", {\r\n      type: 'string',\r\n      role: 'tooltip'\r\n    }]\r\n  ];\r\n\r\n  for (let i = 0; i < provinceData.length; i++) {\r\n    tableData.push([provinceData[i].city, provinceData[i].totalprice, 'Revenue: ' + UTIL.dollarify(provinceData[i].totalprice)]);\r\n  }\r\n\r\n  return tableData;\r\n}\r\n\r\nfunction drawWorldMap() {\r\n  btnBack.style.visibility = 'hidden';\r\n  subTitle = 'Global';\r\n  currentView = VIEW.world;\r\n  worldData = google.visualization.arrayToDataTable(getWorldData());\r\n  chart = new google.visualization.GeoChart(document.getElementById('regions_div'));\r\n  google.visualization.events.addListener(chart, 'regionClick', drawCountryMap);\r\n\r\n\r\n  const worldOptions = {\r\n    legend: {\r\n      textStyle: {\r\n        fontSize: 16\r\n      },\r\n      numberFormat: '\u00c2\u00a4#,##0.00'\r\n    },\r\n    displayMode: 'auto',\r\n    keepAspectRatio: true,\r\n    width: '100%',\r\n    height: '100%'\r\n  };\r\n\r\n  currentData.data = worldData;\r\n  currentData.options = worldOptions;\r\n\r\n  subTitleHTML.innerHTML = subTitle;\r\n  chart.draw(currentData.data, currentData.options);\r\n  \r\n  if (defaultDrillDown && defaultDrillDown.region != \"Global\") {\r\n      google.visualization.events.trigger(chart, 'regionClick', defaultDrillDown);\r\n      \r\n      if (defaultDrillDown.region.length > 2) {\r\n        currentView = VIEW.province;\r\n        previousCountry = {\r\n            region: defaultDrillDown.region.substring(0, 2)\r\n        };\r\n      }\r\n      defaultDrillDown = null;\r\n  }\r\n}\r\n\r\nfunction drawCountryMap(country) {\r\n  if (currentView == VIEW.world) {\r\n    previousCountry = country;\r\n  }\r\n  currentView = VIEW.country;\r\n  btnBack.style.visibility = 'visible';\r\n  let countryStr = country.region.substring(0, 2);\r\n  let hasProvinces = countryStr == 'US' || countryStr == 'CA' || countryStr == 'AU';\r\n  countryData = hasProvinces ? google.visualization.arrayToDataTable(getSolidProvincesData(countryStr)) :\r\n    google.visualization.arrayToDataTable(getCountryData(countryStr));\r\n\r\n  subTitle = country.region;\r\n\r\n  if (country.region.includes('-')) {\r\n    currentView = VIEW.province;\r\n    let provinceStr = country.region.substring(3);\r\n    countryOptions.displayMode = 'markers';\r\n    countryOptions.region = country.region;\r\n    if (countryStr == 'CA' || countryStr == 'AU') {\r\n      countryOptions.region = countryStr;\r\n    }\r\n    let provinceData = google.visualization.arrayToDataTable(getProvinceData(countryStr, provinceStr));\r\n    currentData.data = provinceData;\r\n    currentData.options = countryOptions;\r\n  } else {\r\n    countryOptions.region = countryStr;\r\n    countryOptions.displayMode = hasProvinces ? 'auto' : 'markers';\r\n    currentData.data = countryData;\r\n    currentData.options = countryOptions;\r\n  }\r\n\r\n  chart.draw(currentData.data, currentData.options);\r\n  subTitleHTML.innerHTML = subTitle;\r\n}\r\n\r\nfunction btnBackEvent() {\r\n  if (currentView == VIEW.province) {\r\n    drawCountryMap(previousCountry);\r\n  } else {\r\n    drawWorldMap();\r\n  }\r\n}\r\n\r\nwindow.onresize = function (event) {\r\n  chart.draw(currentData.data, currentData.options);\r\n}\r\n\r\ntitleHTML.innerHTML = \"Sales By Region\";\r\nsubTitleHTML.innerHTML = subTitle;\r\ndescriptionHTML.innerHTML = dateStr;", "2023-01-05 17:28:06.959000", "Query and logic for the Sales By Region page", "Sales By Region", "", 20, 3, "sales-by-region", 0], [11, "_binary \u0001", "<html lang=\"en\">\r\n\r\n<head>\r\n    {% Template Default_Header %}\r\n</head>\r\n\r\n<body>\r\n    <div class=\"overflowHidden\" style=\"position: relative; height: 100%; width: 95vw;\">\r\n        <div id=\"headerContainer\">\r\n            <h1 id=\"title\"></h1>\r\n            <h2 id=\"subTitle\"></h2>\r\n            <h3 id=\"description\"></h3>\r\n        </div>\r\n        <div id=\"chartContainer\">\r\n            <canvas id=\"topSalesman\"></canvas>\r\n        </div>\r\n    </div>\r\n\r\n    <script>\r\n    {% Script Util %}\r\n    {% Script Colors %}\r\n    {% Script Chart_Piece_Label %}\r\n    {% Script Sales_By_Rep %}\r\n    {% Script Print %}\r\n    {% Script Show_Header %}\r\n    </script>\r\n    \r\n</body>\r\n\r\n</html>", "2023-01-05 17:28:06.959000", "Compares fulfilled revenue by rep", "Sales By Rep", "", 10, 5, "sales-by-rep", 1], [12, "_binary \u0001", "const dateRange = $RANGE{Date_Range|this month};\r\n\r\nconst includeReturns = $CHECK{IncludeReturns|false};\r\nconst includeDiscounts = $CHECK{IncludeDiscounts|false};\r\n\r\nconst query = `SELECT so.salesman, SUM(postSoItem.totalPrice) AS totalPrice\r\nFROM postSoItem\r\n    JOIN soItem ON postSoItem.soItemId = soitem.id AND soItem.typeId <> 40 AND soItem.qtyfulfilled > 0\r\n    JOIN so ON soItem.soId = so.id\r\n    JOIN postSo ON postSo.Id = postsoitem.postsoid\r\nWHERE postSo.postDate between '${dateRange.fromDate}' AND '${dateRange.toDate}'\r\n    AND IF(${includeReturns} = 1,1=1,soitem.typeid NOT IN (20,21))\r\n    AND IF(${includeDiscounts} = 1,1=1,soitem.typeid NOT IN (30,31))\r\nGROUP BY so.salesmanId\r\nORDER BY totalPrice DESC`;\r\n\r\nconst data = JSON.parse(runQuery(query));\r\n\r\nconsole.log(query);\r\nconsole.log(data);\r\n\r\nlet dateStr = UTIL.convertDate(dateRange.fromDate, true) + \" - \" + UTIL.convertDate(dateRange.toDate, false);\r\nif (moment(dateRange.fromDate).isSame('1000-01-01', 'year') && moment(dateRange.toDate).isSame('3000-01-01', 'year')) {\r\n  dateStr = 'All';\r\n}\r\n   \r\nfunction createBar(totalPrice, tableColors){\r\n    return {\r\n        backgroundColor: tableColors.halfAlpha,\r\n        borderColor: tableColors.fullAlpha,\r\n        borderWidth: 3,\r\n        data: totalPrice,\r\n    };\r\n}\r\n\r\nconst barLabels = [];\r\nconst barTotalPrices = [];\r\nlet barTotalPriceOverall = 0;\r\nconst chartData = [];\r\n\r\nfor (let salesman = 0; salesman < data.length; salesman++) {\r\n    barLabels.push(data[salesman].salesman);\r\n    barTotalPrices.push(data[salesman].totalprice);\r\n    barTotalPriceOverall += barTotalPrices[salesman];\r\n}\r\n\r\nlet tableColors = COLORS.get(data.length);\r\nchartData.push(createBar(barTotalPrices, tableColors));\r\n\r\nconst barChartData = {\r\n    labels: barLabels,\r\n    datasets: chartData\r\n}\r\n\r\nconst barOptions = {\r\n    title: {\r\n        display: true,\r\n        padding: 3\r\n    },\r\n    mode: 'index',\r\n    position: 'cursor',\r\n    intersect: false,\r\n    legend: {\r\n        display: false,\r\n    },\r\n    scales: {\r\n        xAxes: [{\r\n            ticks: {\r\n                autoSkip: false\r\n            }\r\n        }],\r\n        yAxes: [{\r\n            ticks: {\r\n                beginAtZero: true,\r\n                callback: function(value, index, values) {\r\n                    return UTIL.dollarify(value, 0);\r\n                }\r\n            }\r\n        }]\r\n    },\r\n    tooltips: {\r\n        callbacks: {\r\n            label: (tooltipItem, data) => {\r\n                return UTIL.dollarify(tooltipItem.yLabel);\r\n            },\r\n            title: (tooltipItem, data) => {\r\n                return tooltipItem[0].xLabel;\r\n            }\r\n        },\r\n    },\r\n    responsive: true,\r\n    maintainAspectRatio: false,\r\n    plugins: {\r\n        datalabels: {\r\n            align: 'end',\r\n            anchor: 'end',\r\n            color: '#828891',\r\n            font: {\r\n                weight: 'bold',\r\n                family: 'Helvetica'\r\n            },\r\n            formatter: function(value, context) {\r\n                return UTIL.dollarify(value);\r\n            }\r\n        }\r\n    }\r\n};\r\n\r\nconst ctxBar = document.getElementById('topSalesman');\r\nnew Chart(ctxBar, {\r\n    type: 'bar',\r\n    data: barChartData,\r\n    options: barOptions\r\n});\r\n\r\ndocument.getElementById(\"title\").innerHTML = 'Sales By Rep';\r\ndocument.getElementById(\"subTitle\").innerHTML = dateStr;\r\ndocument.getElementById(\"description\").innerHTML = '<Description>';", "2023-01-05 17:28:06.974000", "Query and logic for the Sales By Rep page", "Sales By Rep", "", 20, 5, "sales-by-rep", 0], [13, "_binary \u0001", "<html lang=\"en\">\r\n\r\n<head>\r\n    {% Template Default_Header %}\r\n</head>\r\n\r\n<body>\r\n    <div class=\"overflowHidden\" style=\"position: relative; height: 100%; width: 100%\">\r\n        <div id=\"headerContainer\">\r\n            <h1 id=\"title\"></h1>\r\n            <h2 id=\"subTitle\"></h2>\r\n            <h3 id=\"description\"></h3>\r\n        </div>\r\n        <div id=\"chartContainer\">\r\n            <canvas id=\"topSalesman\"></canvas>\r\n        </div>\r\n    </div>\r\n\r\n    <script>\r\n    {% Script Util %}\r\n    {% Script Colors %}\r\n    {% Script Chart_Piece_Label %}\r\n    {% Script Sales_Goal %}\r\n    {% Script Print %}\r\n    {% Script Show_Header %}\r\n    </script>\r\n    \r\n</body>\r\n\r\n</html>", "2023-01-05 17:28:06.974000", "Shows progress towards revenue goal", "Sales Goal Chart", "", 10, 3, "sales-goal", 1], [14, "_binary \u0001", "const dateRange = $RANGE{Date_Range|this month};\r\nconst currentSalesColor = '$COLOR{Current_Sales_Color|#33D566}';\r\nlet goal = \"$MONEY{Goal}\";\r\ngoal = Number(goal.replace(/[^0-9\\.-]+/g,\"\"));\r\n\r\nlet rep = \"$USER{Rep|%}\";\r\nif (rep != \"%\"){\r\n    rep = parseInt(rep);\r\n}\r\nif (rep == -1) {\r\n    rep = \"%\";\r\n}\r\n\r\nconst data = JSON.parse(runQuery(\"SELECT sysuser.firstName, sysuser.lastName, DAY(PostSo.postDate) AS PostedDate, SUM(PostSoItem.totalPrice) AS TotalPrice \"\r\n    + \"FROM PostSoItem \"\r\n    + \"JOIN PostSo ON PostSo.id = PostSoItem.postSoId \"\r\n    + \"JOIN SoItem ON PostSoItem.soItemId = SoItem.id AND SoItem.typeId <> 40 \"\r\n    + \"JOIN so ON so.id = soitem.soId \"\r\n    + \"JOIN sysuser ON so.salesmanId = sysuser.id \"\r\n    + \"WHERE postDate >= '\" + dateRange.fromDate + \"' \"\r\n    + \"AND postDate <= '\" + dateRange.toDate + \"' \"\r\n    + \"AND salesmanId LIKE '\" + rep + \"' \"\r\n    + \"GROUP BY CAST(PostSo.postDate AS DATE), sysuser.firstName, sysuser.lastName\"));\r\n\r\nconst doughnutLabels = [\"Current Sales\",\"Remaining Goal\"];\r\nconst doughnutDatasets = [];\r\nconst allSales = []\r\n\r\nlet totalSales = 0;\r\n\r\nfor (let i = 0; i < data.length; i++) {\r\n    totalSales += data[i].totalprice;\r\n}\r\n\r\nconst goalSales = totalSales;\r\nlet remainingGoal = goal - goalSales;\r\nremainingGoal = remainingGoal < 0 ? 0 : remainingGoal; \r\n\r\nallSales.push(goalSales);\r\nallSales.push(remainingGoal);\r\ndoughnutDatasets.push(createDoughnut(allSales, [UTIL.convertHex(currentSalesColor,100),'rgba(0,0,0,0)'],[UTIL.convertHex(currentSalesColor,50),UTIL.convertHex(currentSalesColor,50)]));\r\n\r\nlet dateStr = UTIL.convertDate(dateRange.fromDate, true) + \" - \" + UTIL.convertDate(dateRange.toDate, false);\r\nif (moment(dateRange.fromDate).isSame('1000-01-01', 'year') && moment(dateRange.toDate).isSame('3000-01-01', 'year')) {\r\n  dateStr = 'All';\r\n}\r\n\r\nconst doughnutData = {\r\n    labels: doughnutLabels,\r\n    datasets: doughnutDatasets\r\n};\r\n\r\nconst doughnutOptions = {\r\n    tooltips: {\r\n        callbacks: {\r\n            label: function (tooltipItem, data) {\r\n                return UTIL.dollarify(data.datasets[0].data[tooltipItem.index]);\r\n            },\r\n           title: (tooltipItem, data) => {\r\n                return data.labels[tooltipItem[0].index]; \r\n            }\r\n        }\r\n    },\r\n    plugins: {\r\n        datalabels: {\r\n            color: '#828891',\r\n            display: false,\r\n            font: {\r\n                weight: 'bold',\r\n                family: 'Roboto'\r\n            },\r\n            formatter: function(value, context) {\r\n                return UTIL.dollarify(value);\r\n            }\r\n        }\r\n    },\r\n    responsive: true,\r\n    maintainAspectRatio: false,\r\n    pieceLabel: {\r\n        render: 'label',\r\n        fontColor: '#828891',\r\n        fontSize: 14,\r\n        fontStyle: 'bold',\r\n        position: 'outside',\r\n        render: function (args) {\r\n            let label = (args.value/goal * 100).toFixed(1) + '%';\r\n            return label;\r\n        }\r\n    },\r\n    legend: {\r\n        position: 'bottom',\r\n        display: false\r\n    },\r\n    layout: {\r\n        padding: {\r\n            right: 50,\r\n            left: 50\r\n        }\r\n    },\r\n    \r\n    circumference: Math.PI,\r\n    rotation: Math.PI,\r\n    \r\n};\r\n\r\n// DOM Population =================================================================================\r\n\r\nconst ctxBar = document.getElementById('topSalesman');\r\nnew Chart(ctxBar, {\r\n    type: 'doughnut',\r\n    data: doughnutData,\r\n    options: doughnutOptions\r\n});\r\n\r\nconst titleHtml = document.getElementById(\"title\");\r\nif (rep == \"%\") {\r\n    titleHtml.innerHTML = \"Sales Goal\";\r\n} else if (data[0]) {\r\n    titleHtml.innerHTML = \"Sales Goal - \" + data[0].firstname + ' ' + data[0].lastname;\r\n} else {\r\n    const repName = JSON.parse(runQuery(\"SELECT firstName, lastName FROM SysUser WHERE id='\" + rep + \"'\"));\r\n    titleHtml.innerHTML = \"Sales Goal - \" + repName[0].firstname + ' ' + repName[0].lastname;\r\n}\r\n\r\ndocument.getElementById(\"subTitle\").innerHTML = UTIL.dollarify(totalSales, 0) + \" of \" + UTIL.dollarify(goal, 0) + \" Goal\";\r\ndocument.getElementById(\"description\").innerHTML = dateStr;\r\n\r\n// Function Declarations ==========================================================================\r\n\r\nfunction createDoughnut(data, colors, borderColor){\r\n    return {\r\n        data: data,\r\n        backgroundColor: colors,\r\n        borderColor: borderColor,\r\n        borderWidth: 2\r\n    };\r\n}\r\n", "2023-01-05 17:28:06.990000", "Query and logic for the Sales Goal page", "Sales Goal", "", 20, 3, "sales-goal", 0], [15, "_binary \u0001", "<html lang=\"en\">\r\n\r\n<head>\r\n    {% Template Default_Header %}\r\n</head>\r\n\r\n<body>\r\n    <div class=\"overflowHidden\" style=\"position: relative; height: 100%; width: 95vw;\">\r\n        <div id=\"headerContainer\">\r\n            <h1 id=\"title\"></h1>\r\n            <h2 id=\"subTitle\"></h2>\r\n            <h3 id=\"description\"></h3>\r\n        </div>\r\n        <div id=\"chartContainer\">\r\n            <canvas id=\"productChart\"></canvas>\r\n        </div>\r\n    </div>\r\n\r\n    <script>\r\n    {% Script Util %}\r\n    {% Script Colors %}\r\n    {% Script Chart_Piece_Label %}\r\n    {% Script Top_Products %}\r\n    {% Script Print %}\r\n    {% Script Show_Header %}\r\n    </script>\r\n    \r\n</body>\r\n\r\n</html>", "2023-01-05 17:28:06.990000", "Shows the top products by revenue", "Top Products Chart", "", 10, 4, "top-products", 1], [16, "_binary \u0001", "const numOfProd = $NUM{Number_of_products|5};\r\nconst dateRange = $RANGE{Date_Range|this year};\r\nconst chartOption = \"$LIST{Chart_Type|^bar,pie}\";\r\nconst displayLegend = $CHECK{Display_pie_legend|true};\r\nconst displayMiscSale = $CHECK{Display_Misc_Sales_Items|false};\r\nlet miscSale = \"AND soItem.typeId <> 11 \"\r\nif (displayMiscSale == true) {\r\n    miscSale = \" \";\r\n} else {\r\n    miscSale = \"AND soItem.typeId <> 11 \"\r\n}\r\n\r\nconst data = JSON.parse(runQuery(\"SELECT soItem.productNum, SUM(postSoItem.totalPrice) AS totalPrice from postSoItem \" \r\n    + \"JOIN soItem ON postSoItem.soItemId = soItem.id AND soItem.typeId <> 40 \"\r\n    + \"WHERE statusId <> 40 AND dateLastFulfillment >= '\" + dateRange.fromDate + \"' AND dateLastFulfillment <= '\" + dateRange.toDate + \"' \"\r\n    + miscSale\r\n    + \"GROUP BY productNum \"\r\n    + \"ORDER BY totalPrice \" \r\n    + \"DESC LIMIT \" + numOfProd)); \r\n    \r\nconst other = JSON.parse(runQuery(\"SELECT SUM(totalPrice) AS totalPrice \" \r\n    + \"FROM (SELECT SUM(postSoItem.totalPrice) AS totalPrice \"\r\n    + \"FROM postSoItem \"\r\n    + \"JOIN soItem ON postSoItem.soItemId = soItem.id AND soItem.typeId <> 40 AND soItem.statusId = 50 \"\r\n    + \"JOIN postSo ON postSo.soId = soItem.soId \"\r\n    + \"WHERE postSo.postDate >= '\" + dateRange.fromDate + \"' AND postSo.postDate <= '\" + dateRange.toDate + \"' \"\r\n    + \"GROUP BY productNum \"\r\n    + \"ORDER BY totalPrice DESC \"\r\n    + \"LIMIT \" + numOfProd + \", 18446744073709551615) AS subQuery\"));\r\n    //This offset is MySQL Infitity. See https://dev.mysql.com/doc/refman/5.7/en/select.html#id4651990\r\n    \r\nlet dateStr = UTIL.convertDate(dateRange.fromDate, true) + \" - \" + UTIL.convertDate(dateRange.toDate, false);\r\nif (moment(dateRange.fromDate).isSame('1000-01-01', 'year') && moment(dateRange.toDate).isSame('3000-01-01', 'year')) {\r\n  dateStr = 'All';\r\n}\r\n    \r\nfunction createBar(totalPrice, tableColors){\r\n    return {\r\n        backgroundColor: tableColors.halfAlpha,\r\n        borderColor: tableColors.fullAlpha,\r\n        borderWidth: 3,\r\n        data: totalPrice,\r\n    };\r\n}\r\n\r\nfunction createPie(data, tableColors) {\r\n    //Insert grey (other) into pie chart\r\n    tableColors.halfAlpha.push(UTIL.convertHex('#757575', 50));\r\n    tableColors.fullAlpha.push(UTIL.convertHex('#757575', 100));\r\n    return {\r\n        data: data,\r\n        backgroundColor: tableColors.halfAlpha,\r\n        borderColor: tableColors.fullAlpha,\r\n        borderWidth: 2,\r\n    };\r\n}\r\n\r\nconst barLabels = [];\r\nconst pieLabels = [];\r\nconst barTotalPrices = [];\r\nconst pieTotalPrices = [];\r\nlet barTotalPriceOverall = 0;\r\nlet pieTotalPriceOverall = 0;\r\nconst chartData = [];\r\nconst pieData = [];\r\n\r\nfor (let product = 0; product < data.length; product++) {\r\n    barLabels.push(data[product].productnum);\r\n    pieLabels.push(data[product].productnum);\r\n    barTotalPrices.push(data[product].totalprice);\r\n    pieTotalPrices.push(data[product].totalprice);\r\n    barTotalPriceOverall += barTotalPrices[product];\r\n}\r\n\r\npieTotalPriceOverall = barTotalPriceOverall + other[0].totalprice;\r\n\r\nlet tableColors = COLORS.get(numOfProd);\r\nchartData.push(createBar(barTotalPrices, tableColors));\r\n\r\npieTotalPrices.push(other[0].totalprice);\r\npieData.push(createPie(pieTotalPrices, tableColors));\r\npieLabels.push('Other');\r\n\r\nconst barChartData = {\r\n    labels: barLabels,\r\n    datasets: chartData\r\n}\r\n\r\nconst pieChartData = {\r\n    labels: pieLabels,\r\n    datasets: pieData\r\n}\r\n\r\nconst barOptions = {\r\n    title: {\r\n        display: true,\r\n        padding: 3\r\n    },\r\n    mode: 'index',\r\n    position: 'cursor',\r\n    intersect: false,\r\n    legend: {\r\n        display: false,\r\n    },\r\n    scales: {\r\n        xAxes: [{\r\n            stacked: true,\r\n            ticks: {\r\n                autoSkip: false\r\n            }\r\n        }],\r\n        yAxes: [{\r\n            ticks: {\r\n                beginAtZero: true,\r\n                callback: function(value, index, values) {\r\n                    return UTIL.dollarify(value, 0);\r\n                }\r\n            }\r\n        }]\r\n    },\r\n    tooltips: {\r\n        callbacks: {\r\n            label: (tooltipItem, data) => {\r\n                return UTIL.dollarify(tooltipItem.yLabel);\r\n            },\r\n            title: (tooltipItem, data) => {\r\n                return tooltipItem[0].xLabel;\r\n            }\r\n        },\r\n    },\r\n    responsive: true,\r\n    maintainAspectRatio: false,\r\n    plugins: {\r\n        datalabels: {\r\n            align: 'end',\r\n            anchor: 'end',\r\n            color: '#828891',\r\n            font: {\r\n                weight: 'bold',\r\n                family: 'Helvetica'\r\n            },\r\n            formatter: function(value, context) {\r\n                return UTIL.dollarify(value);\r\n            }\r\n        }\r\n    }\r\n};\r\n\r\nconst pieOptions = {\r\n    plugins: {\r\n        datalabels: {\r\n            display: false\r\n        }\r\n    },\r\n    legend: {\r\n        display: displayLegend\r\n    },\r\n    responsive: true,\r\n    maintainAspectRatio: false,\r\n    pieceLabel: {\r\n        render: 'label',\r\n        fontColor: '#828891',\r\n        fontSize: 14,\r\n        fontStyle: 'bold',\r\n        position: 'outside',\r\n        render: function (args) {\r\n            let label = (args.value/pieTotalPriceOverall * 100).toFixed(1) + '%';\r\n            return label;\r\n        }\r\n      },\r\n    tooltips: {\r\n            backgroundColor: '#ffffff',\r\n            titleFontColor: '#4e5156',\r\n            bodyFontColor: '#4e5156',\r\n            callbacks: {\r\n                label: (tooltipItem, data) => {\r\n                    return (data.datasets[0].data[tooltipItem.index] / pieTotalPriceOverall * 100).toFixed(1) + '%'; \r\n                },\r\n                title: (tooltipItem, data) => {\r\n                    return data.labels[tooltipItem[0].index]; \r\n                }\r\n            }\r\n        }\r\n}\r\n\r\nif(chartOption === 'bar') {\r\n    const ctxBar = document.getElementById('productChart');\r\n    new Chart(ctxBar, {\r\n        type: 'bar',\r\n        data: barChartData,\r\n        options: barOptions\r\n    });\r\n} else {\t\t\t\t\r\n    const ctxPie = document.getElementById('productChart');\r\n    new Chart(ctxPie, {\r\n        type: 'pie',\r\n        data: pieChartData,\r\n        options: pieOptions\r\n    });\r\n}\r\n\r\ndocument.getElementById(\"title\").innerHTML = 'Top ' + numOfProd + ' Products';\r\ndocument.getElementById(\"subTitle\").innerHTML = dateStr;\r\ndocument.getElementById(\"description\").innerHTML = '<Description>';\r\n", "2023-01-05 17:28:07.005000", "Query and logic for the Top Products page", "Top Products", "", 20, 4, "top-products", 0], [17, "_binary \u0001", "const displayHeader = $CHECK{Display_header|true};\r\n\r\nlet headerContainer = document.getElementById('headerContainer');\r\ndisplayHeader ? headerContainer.style.display = 'block' : headerContainer.style.display = 'none';\r\n\r\n\r\n", "2023-01-05 17:28:07.005000", "Logic to hide or display the page header", "Show Header", "", 20, 1, "show-header", 0], [18, "_binary \u0001", "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<meta charset='utf-8' />\r\n\r\n{% Template Bootstrap_Dependencies %}\r\n\r\n<link href='/releases/fullcalendar/3.9.0/fullcalendar.min.css' rel='stylesheet' />\r\n<link href='/releases/fullcalendar/3.9.0/fullcalendar.print.css' rel='stylesheet' media='print' />\r\n<script src='/assets/demo-to-codepen.js'></script>\r\n\r\n\r\n<style>\r\n\r\n  html, body {\r\n  margin: 0;\r\n  padding: 0;\r\n  font-family: \"Lucida Grande\",Helvetica,Arial,Verdana,sans-serif;\r\n  font-size: 14px;\r\n}\r\n\r\n#calendar {\r\n  max-width: 900px;\r\n  margin: 40px auto;\r\n}\r\n{% Style Calendar_Styling %}\r\n{% Style Print_Landscape %}\r\n</style>\r\n\r\n\r\n<script>\r\n{% Script Capacity_Planning %}\r\n</script>\r\n\r\n</head>\r\n\r\n  <div id='calendar'></div>\r\n</body>\r\n\r\n</html>\r\n", "2023-01-05 17:28:07.005000", "A report that displays your scheduled work orders and your total time scheduled per day. Also allows you to reschedule those Work Orders to manage your schedule.", "Capacity Planning Report", "", 10, 3, "capacity-planning", 1], [19, "_binary \u0001", "<script src=\"https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js\"></script>\r\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.js\"></script>\r\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css\">\r\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.css\">\r\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js\"></script>\r\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.js\"></script>\r\n\r\n\r\n<!-- JQUERY UI -->\r\n<script src=\"https://code.jquery.com/ui/1.12.1/jquery-ui.js\"  integrity=\"sha256-T0Vest3yCU7pafRw9r+settMBX6JkKN06dqBnpQ8d30=\"  crossorigin=\"anonymous\"></script>\r\n\r\n<!-- Calendar Plugin -->\r\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.9.0/fullcalendar.min.js\"></script>\r\n\r\n", "2023-01-05 17:28:07.021000", "The necessary includes for bootstrap tables", "Bootstrap Dependencies", "", 40, 3, "capacity-planning", 0], [20, "_binary \u0001", "/*!\r\n * FullCalendar v3.9.0\r\n * Docs & License: https://fullcalendar.io/\r\n * (c) 2018 Adam Shaw\r\n */\r\n.fc {\r\n    direction: ltr;\r\n    text-align: left; }\r\n    \r\ninput[type=number]{\r\n                width: 33px;\r\n                border: none;\r\n                border-color: transparent;\r\n                background: #f7f5ed;\r\n            }  \r\n     \r\n  .fc-rtl {\r\n    text-align: right; }\r\n  \r\n  body .fc {\r\n    /* extra precedence to overcome jqui */\r\n    font-size: 1em; }\r\n  \r\n  /* Colors\r\n    --------------------------------------------------------------------------------------------------*/\r\n    .fc-highlight {\r\n      /* when user is selecting cells */\r\n      background: #bce8f1;\r\n      opacity: .3; }\r\n    \r\n    .fc-bgevent {\r\n      /* default look for background events */\r\n      background: #8fdf82;\r\n      opacity: .3; }\r\n    \r\n    .fc-nonbusiness {\r\n      /* default look for non-business-hours areas */\r\n      /* will inherit .fc-bgevent's styles */\r\n      background: #d7d7d7; }\r\n  \r\n  /* Buttons (styled <button> tags, normalized to work cross-browser)\r\n    --------------------------------------------------------------------------------------------------*/\r\n    .fc button {\r\n      /* force height to include the border and padding */\r\n      -moz-box-sizing: border-box;\r\n      -webkit-box-sizing: border-box;\r\n      box-sizing: border-box;\r\n      /* dimensions */\r\n      margin: 0;\r\n      height: 2.1em;\r\n      padding: 0 .6em;\r\n      /* text & cursor */\r\n      font-size: 1em;\r\n      /* normalize */\r\n      white-space: nowrap;\r\n      cursor: pointer; }\r\n    \r\n    /* Firefox has an annoying inner border */\r\n    .fc button::-moz-focus-inner {\r\n      margin: 0;\r\n      padding: 0; }\r\n    \r\n    .fc-state-default {\r\n      /* non-theme */\r\n      border: 1px solid; }\r\n    \r\n    .fc-state-default.fc-corner-left {\r\n      /* non-theme */\r\n      border-top-left-radius: 4px;\r\n      border-bottom-left-radius: 4px; }\r\n    \r\n    .fc-state-default.fc-corner-right {\r\n      /* non-theme */\r\n      border-top-right-radius: 4px;\r\n      border-bottom-right-radius: 4px; }\r\n    \r\n    /* icons in buttons */\r\n    .fc button .fc-icon {\r\n      /* non-theme */\r\n      position: relative;\r\n      top: -0.05em;\r\n      /* seems to be a good adjustment across browsers */\r\n      margin: 0 .2em;\r\n      vertical-align: middle; }\r\n    \r\n    /*\r\n      button states\r\n      borrowed from twitter bootstrap (http://twitter.github.com/bootstrap/)\r\n    */\r\n    .fc-state-default {\r\n      background-color: #f5f5f5;\r\n      background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);\r\n      background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));\r\n      background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);\r\n      background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);\r\n      background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);\r\n      background-repeat: repeat-x;\r\n      border-color: #e6e6e6 #e6e6e6 #bfbfbf;\r\n      border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\r\n      color: #333;\r\n      text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);\r\n      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); }\r\n    \r\n    .fc-state-hover,\r\n    .fc-state-down,\r\n    .fc-state-active,\r\n    .fc-state-disabled {\r\n      color: #333333;\r\n      background-color: #e6e6e6; }\r\n    \r\n    .fc-state-hover {\r\n      color: #333333;\r\n      text-decoration: none;\r\n      background-position: 0 -15px;\r\n      -webkit-transition: background-position 0.1s linear;\r\n      -moz-transition: background-position 0.1s linear;\r\n      -o-transition: background-position 0.1s linear;\r\n      transition: background-position 0.1s linear; }\r\n    \r\n    .fc-state-down,\r\n    .fc-state-active {\r\n      background-color: #cccccc;\r\n      background-image: none;\r\n      box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); }\r\n    \r\n    .fc-state-disabled {\r\n      cursor: default;\r\n      background-image: none;\r\n      opacity: 0.65;\r\n      box-shadow: none; }\r\n    \r\n  /* Buttons Groups\r\n    --------------------------------------------------------------------------------------------------*/\r\n    .fc-button-group {\r\n      display: inline-block; }\r\n    \r\n    /*\r\n    every button that is not first in a button group should scootch over one pixel and cover the\r\n    previous button's border...\r\n    */\r\n    .fc .fc-button-group > * {\r\n      /* extra precedence b/c buttons have margin set to zero */\r\n      float: left;\r\n      margin: 0 0 0 -1px; }\r\n    \r\n    .fc .fc-button-group > :first-child {\r\n      /* same */\r\n      margin-left: 0; }\r\n  \r\n  /* Popover\r\n    --------------------------------------------------------------------------------------------------*/\r\n    .fc-popover {\r\n      position: absolute;\r\n      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15); }\r\n    \r\n    .fc-popover .fc-header {\r\n      /* TODO: be more consistent with fc-head/fc-body */\r\n      padding: 2px 4px; }\r\n    \r\n    .fc-popover .fc-header .fc-title {\r\n      margin: 0 2px; }\r\n    \r\n    .fc-popover .fc-header .fc-close {\r\n      cursor: pointer; }\r\n    \r\n    .fc-ltr .fc-popover .fc-header .fc-title,\r\n    .fc-rtl .fc-popover .fc-header .fc-close {\r\n      float: left; }\r\n    \r\n    .fc-rtl .fc-popover .fc-header .fc-title,\r\n    .fc-ltr .fc-popover .fc-header .fc-close {\r\n      float: right; }\r\n  \r\n  /* Misc Reusable Components\r\n     --------------------------------------------------------------------------------------------------*/\r\n     .fc-divider {\r\n       border-style: solid;\r\n       border-width: 1px; }\r\n     \r\n     hr.fc-divider {\r\n       height: 0;\r\n       margin: 0;\r\n       padding: 0 0 2px;\r\n       /* height is unreliable across browsers, so use padding */\r\n       border-width: 1px 0; }\r\n     \r\n     .fc-clear {\r\n       clear: both; }\r\n     \r\n     .fc-bg,\r\n     .fc-bgevent-skeleton,\r\n     .fc-highlight-skeleton,\r\n     .fc-helper-skeleton {\r\n       /* these element should always cling to top-left/right corners */\r\n       position: absolute;\r\n       top: 0;\r\n       left: 0;\r\n       right: 0; }\r\n     \r\n     .fc-bg {\r\n       bottom: 0;\r\n       /* strech bg to bottom edge */ }\r\n     \r\n     .fc-bg table {\r\n       height: 100%;\r\n       /* strech bg to bottom edge */ }\r\n  \r\n  /* Tables\r\n    --------------------------------------------------------------------------------------------------*/\r\n    .fc table {\r\n      width: 100%;\r\n      box-sizing: border-box;\r\n      /* fix scrollbar issue in firefox */\r\n      table-layout: fixed;\r\n      border-collapse: collapse;\r\n      border-spacing: 0;\r\n      font-size: 1em;\r\n      /* normalize cross-browser */ }\r\n    \r\n    .fc th {\r\n      text-align: center; }\r\n    \r\n    .fc th,\r\n    .fc td {\r\n      border-style: solid;\r\n      border-width: 1px;\r\n      padding: 0;\r\n      vertical-align: top; }\r\n    \r\n    .fc td.fc-today {\r\n      border-style: double;\r\n      /* overcome neighboring borders */ }\r\n  \r\n  /* Internal Nav Links\r\n    --------------------------------------------------------------------------------------------------*/\r\n    a[data-goto] {\r\n      cursor: pointer; }\r\n    \r\n    a[data-goto]:hover {\r\n      text-decoration: underline; }\r\n  \r\n  /* Fake Table Rows\r\n    --------------------------------------------------------------------------------------------------*/\r\n    .fc .fc-row {\r\n      /* extra precedence to overcome themes w/ .ui-widget-content forcing a 1px border */\r\n      /* no visible border by default. but make available if need be (scrollbar width compensation) */\r\n      border-style: solid;\r\n      border-width: 0; }\r\n    \r\n    .fc-row table {\r\n      /* don't put left/right border on anything within a fake row.\r\n         the outer tbody will worry about this */\r\n      border-left: 0 hidden transparent;\r\n      border-right: 0 hidden transparent;\r\n      /* no bottom borders on rows */\r\n      border-bottom: 0 hidden transparent; }\r\n    \r\n    .fc-row:first-child table {\r\n      border-top: 0 hidden transparent;\r\n      /* no top border on first row */ }\r\n  \r\n  /* Day Row (used within the header and the DayGrid)\r\n    --------------------------------------------------------------------------------------------------*/\r\n    .fc-row {\r\n      position: relative; }\r\n    \r\n    .fc-row .fc-bg {\r\n      z-index: 1; }\r\n    \r\n    /* highlighting cells & background event skeleton */\r\n    .fc-row .fc-bgevent-skeleton,\r\n    .fc-row .fc-highlight-skeleton {\r\n      bottom: 0;\r\n      /* stretch skeleton to bottom of row */ }\r\n    \r\n    .fc-row .fc-bgevent-skeleton table,\r\n    .fc-row .fc-highlight-skeleton table {\r\n      height: 100%;\r\n      /* stretch skeleton to bottom of row */ }\r\n    \r\n    .fc-row .fc-highlight-skeleton td,\r\n    .fc-row .fc-bgevent-skeleton td {\r\n      border-color: transparent; }\r\n    \r\n    .fc-row .fc-bgevent-skeleton {\r\n      z-index: 2; }\r\n    \r\n    .fc-row .fc-highlight-skeleton {\r\n      z-index: 3; }\r\n    \r\n    /*\r\n    row content (which contains day/week numbers and events) as well as \"helper\" (which contains\r\n    temporary rendered events).\r\n    */\r\n    .fc-row .fc-content-skeleton {\r\n      position: relative;\r\n      z-index: 4;\r\n      padding-bottom: 2px;\r\n      /* matches the space above the events */ }\r\n    \r\n    .fc-row .fc-helper-skeleton {\r\n      z-index: 5; }\r\n    \r\n    .fc .fc-row .fc-content-skeleton table,\r\n    .fc .fc-row .fc-content-skeleton td,\r\n    .fc .fc-row .fc-helper-skeleton td {\r\n      /* see-through to the background below */\r\n      /* extra precedence to prevent theme-provided backgrounds */\r\n      background: none;\r\n      /* in case <td>s are globally styled */\r\n      border-color: transparent; }\r\n    \r\n    .fc-row .fc-content-skeleton td,\r\n    .fc-row .fc-helper-skeleton td {\r\n      /* don't put a border between events and/or the day number */\r\n      border-bottom: 0; }\r\n    \r\n    .fc-row .fc-content-skeleton tbody td,\r\n    .fc-row .fc-helper-skeleton tbody td {\r\n      /* don't put a border between event cells */\r\n      border-top: 0; }\r\n  \r\n  /* Scrolling Container\r\n    --------------------------------------------------------------------------------------------------*/\r\n    .fc-scroller {\r\n      -webkit-overflow-scrolling: touch; }\r\n    \r\n    /* TODO: move to agenda/basic */\r\n    .fc-scroller > .fc-day-grid,\r\n    .fc-scroller > .fc-time-grid {\r\n      position: relative;\r\n      /* re-scope all positions */\r\n      width: 100%;\r\n      /* hack to force re-sizing this inner element when scrollbars appear/disappear */ }\r\n  \r\n  /* Global Event Styles\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-event {\r\n    position: relative;\r\n    /* for resize handle and other inner positioning */\r\n    display: block;\r\n    /* make the <a> tag block */\r\n    font-size: .85em;\r\n    line-height: 1.3;\r\n    border-radius: 3px;\r\n    border: 1px solid #3a87ad;\r\n    /* default BORDER color */ }\r\n  \r\n  .fc-event,\r\n  .fc-event-dot {\r\n    background-color: #3a87ad;\r\n    /* default BACKGROUND color */ }\r\n  \r\n  .fc-event,\r\n  .fc-event:hover {\r\n    color: #fff;\r\n    /* default TEXT color */\r\n    text-decoration: none;\r\n    /* if <a> has an href */ }\r\n  \r\n  .fc-event[href],\r\n  .fc-event.fc-draggable {\r\n    cursor: pointer;\r\n    /* give events with links and draggable events a hand mouse pointer */ }\r\n  \r\n  .fc-not-allowed,\r\n  .fc-not-allowed .fc-event {\r\n    /* to override an event's custom cursor */\r\n    cursor: not-allowed; }\r\n  \r\n  .fc-event .fc-bg {\r\n    /* the generic .fc-bg already does position */\r\n    z-index: 1;\r\n    background: #fff;\r\n    opacity: .25; }\r\n  \r\n  .fc-event .fc-content {\r\n    position: relative;\r\n    z-index: 2; }\r\n  \r\n  /* resizer (cursor AND touch devices) */\r\n  .fc-event .fc-resizer {\r\n    position: absolute;\r\n    z-index: 4; }\r\n  \r\n  /* resizer (touch devices) */\r\n  .fc-event .fc-resizer {\r\n    display: none; }\r\n  \r\n  .fc-event.fc-allow-mouse-resize .fc-resizer,\r\n  .fc-event.fc-selected .fc-resizer {\r\n    /* only show when hovering or selected (with touch) */\r\n    display: block; }\r\n  \r\n  /* hit area */\r\n  .fc-event.fc-selected .fc-resizer:before {\r\n    /* 40x40 touch area */\r\n    content: \"\";\r\n    position: absolute;\r\n    z-index: 9999;\r\n    /* user of this util can scope within a lower z-index */\r\n    top: 50%;\r\n    left: 50%;\r\n    width: 40px;\r\n    height: 40px;\r\n    margin-left: -20px;\r\n    margin-top: -20px; }\r\n  \r\n  /* Event Selection (only for touch devices)\r\n    --------------------------------------------------------------------------------------------------*/\r\n    .fc-event.fc-selected {\r\n      z-index: 9999 !important;\r\n      /* overcomes inline z-index */\r\n      box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); }\r\n    \r\n    .fc-event.fc-selected.fc-dragging {\r\n      box-shadow: 0 2px 7px rgba(0, 0, 0, 0.3); }\r\n  \r\n  /* Horizontal Events\r\n  --------------------------------------------------------------------------------------------------*/\r\n  /* bigger touch area when selected */\r\n  .fc-h-event.fc-selected:before {\r\n    content: \"\";\r\n    position: absolute;\r\n    z-index: 3;\r\n    /* below resizers */\r\n    top: -10px;\r\n    bottom: -10px;\r\n    left: 0;\r\n    right: 0; }\r\n  \r\n  /* events that are continuing to/from another week. kill rounded corners and butt up against edge */\r\n  .fc-ltr .fc-h-event.fc-not-start,\r\n  .fc-rtl .fc-h-event.fc-not-end {\r\n    margin-left: 0;\r\n    border-left-width: 0;\r\n    padding-left: 1px;\r\n    /* replace the border with padding */\r\n    border-top-left-radius: 0;\r\n    border-bottom-left-radius: 0; }\r\n  \r\n  .fc-ltr .fc-h-event.fc-not-end,\r\n  .fc-rtl .fc-h-event.fc-not-start {\r\n    margin-right: 0;\r\n    border-right-width: 0;\r\n    padding-right: 1px;\r\n    /* replace the border with padding */\r\n    border-top-right-radius: 0;\r\n    border-bottom-right-radius: 0; }\r\n  \r\n  /* resizer (cursor AND touch devices) */\r\n  /* left resizer  */\r\n  .fc-ltr .fc-h-event .fc-start-resizer,\r\n  .fc-rtl .fc-h-event .fc-end-resizer {\r\n    cursor: w-resize;\r\n    left: -1px;\r\n    /* overcome border */ }\r\n  \r\n  /* right resizer */\r\n  .fc-ltr .fc-h-event .fc-end-resizer,\r\n  .fc-rtl .fc-h-event .fc-start-resizer {\r\n    cursor: e-resize;\r\n    right: -1px;\r\n    /* overcome border */ }\r\n  \r\n  /* resizer (mouse devices) */\r\n  .fc-h-event.fc-allow-mouse-resize .fc-resizer {\r\n    width: 7px;\r\n    top: -1px;\r\n    /* overcome top border */\r\n    bottom: -1px;\r\n    /* overcome bottom border */ }\r\n  \r\n  /* resizer (touch devices) */\r\n  .fc-h-event.fc-selected .fc-resizer {\r\n    /* 8x8 little dot */\r\n    border-radius: 4px;\r\n    border-width: 1px;\r\n    width: 6px;\r\n    height: 6px;\r\n    border-style: solid;\r\n    border-color: inherit;\r\n    background: #fff;\r\n    /* vertically center */\r\n    top: 50%;\r\n    margin-top: -4px; }\r\n  \r\n  /* left resizer  */\r\n  .fc-ltr .fc-h-event.fc-selected .fc-start-resizer,\r\n  .fc-rtl .fc-h-event.fc-selected .fc-end-resizer {\r\n    margin-left: -4px;\r\n    /* centers the 8x8 dot on the left edge */ }\r\n  \r\n  /* right resizer */\r\n  .fc-ltr .fc-h-event.fc-selected .fc-end-resizer,\r\n  .fc-rtl .fc-h-event.fc-selected .fc-start-resizer {\r\n    margin-right: -4px;\r\n    /* centers the 8x8 dot on the right edge */ }\r\n  \r\n  /* DayGrid events\r\n    ----------------------------------------------------------------------------------------------------\r\n    We use the full \"fc-day-grid-event\" class instead of using descendants because the event won't\r\n    be a descendant of the grid when it is being dragged.\r\n    */\r\n    .fc-day-grid-event {\r\n      margin: 1px 2px 0;\r\n      /* spacing between events and edges */\r\n      padding: 0 1px; }\r\n    \r\n    tr:first-child > td > .fc-day-grid-event {\r\n      margin-top: 2px;\r\n      /* a little bit more space before the first event */ }\r\n    \r\n    .fc-day-grid-event.fc-selected:after {\r\n      content: \"\";\r\n      position: absolute;\r\n      z-index: 1;\r\n      /* same z-index as fc-bg, behind text */\r\n      /* overcome the borders */\r\n      top: -1px;\r\n      right: -1px;\r\n      bottom: -1px;\r\n      left: -1px;\r\n      /* darkening effect */\r\n      background: #000;\r\n      opacity: .25; }\r\n    \r\n    .fc-day-grid-event .fc-content {\r\n      /* force events to be one-line tall */\r\n      white-space: nowrap;\r\n      overflow: hidden; }\r\n    \r\n    .fc-day-grid-event .fc-time {\r\n      font-weight: bold; }\r\n    \r\n    /* resizer (cursor devices) */\r\n    /* left resizer  */\r\n    .fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer,\r\n    .fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer {\r\n      margin-left: -2px;\r\n      /* to the day cell's edge */ }\r\n    \r\n    /* right resizer */\r\n    .fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer,\r\n    .fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer {\r\n      margin-right: -2px;\r\n      /* to the day cell's edge */ }\r\n    \r\n  /* Event Limiting\r\n    --------------------------------------------------------------------------------------------------*/\r\n    /* \"more\" link that represents hidden events */\r\n    a.fc-more {\r\n      margin: 1px 3px;\r\n      font-size: .85em;\r\n      cursor: pointer;\r\n      text-decoration: none; }\r\n    \r\n    a.fc-more:hover {\r\n      text-decoration: underline; }\r\n    \r\n    .fc-limited {\r\n      /* rows and cells that are hidden because of a \"more\" link */\r\n      display: none; }\r\n    \r\n    /* popover that appears when \"more\" link is clicked */\r\n    .fc-day-grid .fc-row {\r\n      z-index: 1;\r\n      /* make the \"more\" popover one higher than this */ }\r\n    \r\n    .fc-more-popover {\r\n      z-index: 2;\r\n      width: 220px; }\r\n    \r\n    .fc-more-popover .fc-event-container {\r\n      padding: 10px; }\r\n  \r\n  /* Now Indicator\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-now-indicator {\r\n    position: absolute;\r\n    border: 0 solid red; }\r\n  \r\n  /* Utilities\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-unselectable {\r\n    -webkit-user-select: none;\r\n  -khtml-user-select: none;\r\n  -moz-user-select: none;\r\n  -ms-user-select: none;\r\n  user-select: none;\r\n  -webkit-touch-callout: none;\r\n  -webkit-tap-highlight-color: transparent; }\r\n  \r\n  /*\r\n  TODO: more distinction between this file and common.css\r\n  */\r\n  /* Colors\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-unthemed th,\r\n  .fc-unthemed td,\r\n  .fc-unthemed thead,\r\n  .fc-unthemed tbody,\r\n  .fc-unthemed .fc-divider,\r\n  .fc-unthemed .fc-row,\r\n  .fc-unthemed .fc-content,\r\n  .fc-unthemed .fc-popover,\r\n  .fc-unthemed .fc-list-view,\r\n  .fc-unthemed .fc-list-heading td {\r\n    border-color: #ddd; }\r\n  \r\n  .fc-unthemed .fc-popover {\r\n    background-color: #fff; }\r\n  \r\n  .fc-unthemed .fc-divider,\r\n  .fc-unthemed .fc-popover .fc-header,\r\n  .fc-unthemed .fc-list-heading td {\r\n    background: #eee; }\r\n  \r\n  .fc-unthemed .fc-popover .fc-header .fc-close {\r\n    color: #666; }\r\n  \r\n  .fc-unthemed td.fc-today {\r\n    background: #fcf8e3; }\r\n  \r\n  .fc-unthemed .fc-disabled-day {\r\n    background: #d7d7d7;\r\n    opacity: .3; }\r\n  \r\n  /* Icons (inline elements with styled text that mock arrow icons)\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-icon {\r\n    display: inline-block;\r\n    height: 1em;\r\n    line-height: 1em;\r\n    font-size: 1em;\r\n    text-align: center;\r\n    overflow: hidden;\r\n    font-family: \"Courier New\", Courier, monospace;\r\n    /* don't allow browser text-selection */\r\n    -webkit-touch-callout: none;\r\n    -webkit-user-select: none;\r\n    -khtml-user-select: none;\r\n    -moz-user-select: none;\r\n    -ms-user-select: none;\r\n    user-select: none; }\r\n  \r\n  /*\r\n  Acceptable font-family overrides for individual icons:\r\n    \"Arial\", sans-serif\r\n    \"Times New Roman\", serif\r\n  \r\n  NOTE: use percentage font sizes or else old IE chokes\r\n  */\r\n  .fc-icon:after {\r\n    position: relative; }\r\n  \r\n  .fc-icon-left-single-arrow:after {\r\n    content: \"\\2039\";\r\n    font-weight: bold;\r\n    font-size: 200%;\r\n    top: -7%; }\r\n  \r\n  .fc-icon-right-single-arrow:after {\r\n    content: \"\\203A\";\r\n    font-weight: bold;\r\n    font-size: 200%;\r\n    top: -7%; }\r\n  \r\n  .fc-icon-left-double-arrow:after {\r\n    content: \"\\AB\";\r\n    font-size: 160%;\r\n    top: -7%; }\r\n  \r\n  .fc-icon-right-double-arrow:after {\r\n    content: \"\\BB\";\r\n    font-size: 160%;\r\n    top: -7%; }\r\n  \r\n  .fc-icon-left-triangle:after {\r\n    content: \"\\25C4\";\r\n    font-size: 125%;\r\n    top: 3%; }\r\n  \r\n  .fc-icon-right-triangle:after {\r\n    content: \"\\25BA\";\r\n    font-size: 125%;\r\n    top: 3%; }\r\n  \r\n  .fc-icon-down-triangle:after {\r\n    content: \"\\25BC\";\r\n    font-size: 125%;\r\n    top: 2%; }\r\n  \r\n  .fc-icon-x:after {\r\n    content: \"\\D7\";\r\n    font-size: 200%;\r\n    top: 6%; }\r\n  \r\n  /* Popover\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-unthemed .fc-popover {\r\n    border-width: 1px;\r\n    border-style: solid; }\r\n  \r\n  .fc-unthemed .fc-popover .fc-header .fc-close {\r\n    font-size: .9em;\r\n    margin-top: 2px; }\r\n  \r\n  /* List View\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-unthemed .fc-list-item:hover td {\r\n    background-color: #f5f5f5; }\r\n  \r\n  /* Colors\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .ui-widget .fc-disabled-day {\r\n    background-image: none; }\r\n  \r\n  /* Popover\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-popover > .ui-widget-header + .ui-widget-content {\r\n    border-top: 0;\r\n    /* where they meet, let the header have the border */ }\r\n  \r\n  /* Global Event Styles\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .ui-widget .fc-event {\r\n    /* overpower jqui's styles on <a> tags. TODO: more DRY */\r\n    color: #fff;\r\n    /* default TEXT color */\r\n    text-decoration: none;\r\n    /* if <a> has an href */\r\n    /* undo ui-widget-header bold */\r\n    font-weight: normal; }\r\n  \r\n  /* TimeGrid axis running down the side (for both the all-day area and the slot area)\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .ui-widget td.fc-axis {\r\n    font-weight: normal;\r\n    /* overcome bold */ }\r\n  \r\n  /* TimeGrid Slats (lines that run horizontally)\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-time-grid .fc-slats .ui-widget-content {\r\n    background: none;\r\n    /* see through to fc-bg */ }\r\n  \r\n  .fc.fc-bootstrap3 a {\r\n    text-decoration: none; }\r\n  \r\n  .fc.fc-bootstrap3 a[data-goto]:hover {\r\n    text-decoration: underline; }\r\n  \r\n  .fc-bootstrap3 hr.fc-divider {\r\n    border-color: inherit; }\r\n  \r\n  .fc-bootstrap3 .fc-today.alert {\r\n    border-radius: 0; }\r\n  \r\n  /* Popover\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-bootstrap3 .fc-popover .panel-body {\r\n    padding: 0; }\r\n  \r\n  /* TimeGrid Slats (lines that run horizontally)\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-bootstrap3 .fc-time-grid .fc-slats table {\r\n    /* some themes have background color. see through to slats */\r\n    background: none; }\r\n  \r\n  .fc.fc-bootstrap4 a {\r\n    text-decoration: none; }\r\n  \r\n  .fc.fc-bootstrap4 a[data-goto]:hover {\r\n    text-decoration: underline; }\r\n  \r\n  .fc-bootstrap4 hr.fc-divider {\r\n    border-color: inherit; }\r\n  \r\n  .fc-bootstrap4 .fc-today.alert {\r\n    border-radius: 0; }\r\n  \r\n  .fc-bootstrap4 a.fc-event:not([href]):not([tabindex]) {\r\n    color: #fff; }\r\n  \r\n  .fc-bootstrap4 .fc-popover.card {\r\n    position: absolute; }\r\n  \r\n  /* Popover\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-bootstrap4 .fc-popover .card-body {\r\n    padding: 0; }\r\n  \r\n  /* TimeGrid Slats (lines that run horizontally)\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-bootstrap4 .fc-time-grid .fc-slats table {\r\n    /* some themes have background color. see through to slats */\r\n    background: none; }\r\n  \r\n  /* Toolbar\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-toolbar {\r\n    text-align: center; }\r\n  \r\n  .fc-toolbar.fc-header-toolbar {\r\n    margin-bottom: 1em; }\r\n  \r\n  .fc-toolbar.fc-footer-toolbar {\r\n    margin-top: 1em; }\r\n  \r\n  .fc-toolbar .fc-left {\r\n    float: left; }\r\n  \r\n  .fc-toolbar .fc-right {\r\n    float: right; }\r\n  \r\n  .fc-toolbar .fc-center {\r\n    display: inline-block; }\r\n  \r\n  /* the things within each left/right/center section */\r\n  .fc .fc-toolbar > * > * {\r\n    /* extra precedence to override button border margins */\r\n    float: left;\r\n    margin-left: .75em; }\r\n  \r\n  /* the first thing within each left/center/right section */\r\n  .fc .fc-toolbar > * > :first-child {\r\n    /* extra precedence to override button border margins */\r\n    margin-left: 0; }\r\n  \r\n  /* title text */\r\n  .fc-toolbar h2 {\r\n    margin: 0; }\r\n  \r\n  /* button layering (for border precedence) */\r\n  .fc-toolbar button {\r\n    position: relative; }\r\n  \r\n  .fc-toolbar .fc-state-hover,\r\n  .fc-toolbar .ui-state-hover {\r\n    z-index: 2; }\r\n  \r\n  .fc-toolbar .fc-state-down {\r\n    z-index: 3; }\r\n  \r\n  .fc-toolbar .fc-state-active,\r\n  .fc-toolbar .ui-state-active {\r\n    z-index: 4; }\r\n  \r\n  .fc-toolbar button:focus {\r\n    z-index: 5; }\r\n  \r\n  /* View Structure\r\n  --------------------------------------------------------------------------------------------------*/\r\n  /* undo twitter bootstrap's box-sizing rules. normalizes positioning techniques */\r\n  /* don't do this for the toolbar because we'll want bootstrap to style those buttons as some pt */\r\n  .fc-view-container *,\r\n  .fc-view-container *:before,\r\n  .fc-view-container *:after {\r\n    -webkit-box-sizing: content-box;\r\n    -moz-box-sizing: content-box;\r\n    box-sizing: content-box; }\r\n  \r\n  .fc-view,\r\n  .fc-view > table {\r\n    /* so dragged elements can be above the view's main element */\r\n    position: relative;\r\n    z-index: 1; }\r\n  \r\n  /* BasicView\r\n     --------------------------------------------------------------------------------------------------*/\r\n     /* day row structure */\r\n     .fc-basicWeek-view .fc-content-skeleton,\r\n     .fc-basicDay-view .fc-content-skeleton {\r\n       /* there may be week numbers in these views, so no padding-top */\r\n       padding-bottom: 1em;\r\n       /* ensure a space at bottom of cell for user selecting/clicking */ }\r\n     \r\n     .fc-basic-view .fc-body .fc-row {\r\n       min-height: 4em;\r\n       /* ensure that all rows are at least this tall */ }\r\n     \r\n     /* a \"rigid\" row will take up a constant amount of height because content-skeleton is absolute */\r\n     .fc-row.fc-rigid {\r\n       overflow: hidden; }\r\n     \r\n     .fc-row.fc-rigid .fc-content-skeleton {\r\n       position: absolute;\r\n       top: 0;\r\n       left: 0;\r\n       right: 0; }\r\n     \r\n     /* week and day number styling */\r\n     .fc-day-top.fc-other-month {\r\n       opacity: 0.3; }\r\n     \r\n     .fc-basic-view .fc-week-number,\r\n     .fc-basic-view .fc-day-number {\r\n       padding: 2px; }\r\n     \r\n     .fc-basic-view th.fc-week-number,\r\n     .fc-basic-view th.fc-day-number {\r\n       padding: 0 2px;\r\n       /* column headers can't have as much v space */ }\r\n     \r\n     .fc-ltr .fc-basic-view .fc-day-top .fc-day-number {\r\n    float: right;\r\n    }\r\n     \r\n     .fc-rtl .fc-basic-view .fc-day-top .fc-day-number {\r\n      float: left;  }\r\n     \r\n     .fc-ltr .fc-basic-view .fc-day-top .fc-week-number {\r\n       float: left;\r\n       border-radius: 0 0 3px 0; }\r\n     \r\n     .fc-rtl .fc-basic-view .fc-day-top .fc-week-number {\r\n       float: right;\r\n       border-radius: 0 0 0 3px; }\r\n     \r\n     .fc-basic-view .fc-day-top .fc-week-number {\r\n       min-width: 1.5em;\r\n       text-align: center;\r\n       background-color: #f2f2f2;\r\n       color: #808080; }\r\n     \r\n     /* when week/day number have own column */\r\n     .fc-basic-view td.fc-week-number {\r\n       text-align: center; }\r\n     \r\n     .fc-basic-view td.fc-week-number > * {\r\n       /* work around the way we do column resizing and ensure a minimum width */\r\n       display: inline-block;\r\n       min-width: 1.25em; }\r\n     \r\n  /* AgendaView all-day area\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-agenda-view .fc-day-grid {\r\n    position: relative;\r\n    z-index: 2;\r\n    /* so the \"more..\" popover will be over the time grid */ }\r\n  \r\n  .fc-agenda-view .fc-day-grid .fc-row {\r\n    min-height: 3em;\r\n    /* all-day section will never get shorter than this */ }\r\n  \r\n  .fc-agenda-view .fc-day-grid .fc-row .fc-content-skeleton {\r\n    padding-bottom: 1em;\r\n    /* give space underneath events for clicking/selecting days */ }\r\n  \r\n  /* TimeGrid axis running down the side (for both the all-day area and the slot area)\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc .fc-axis {\r\n    /* .fc to overcome default cell styles */\r\n    vertical-align: middle;\r\n    padding: 0 4px;\r\n    white-space: nowrap; }\r\n  \r\n  .fc-ltr .fc-axis {\r\n    text-align: right; }\r\n  \r\n  .fc-rtl .fc-axis {\r\n    text-align: left; }\r\n  \r\n  /* TimeGrid Structure\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-time-grid-container,\r\n  .fc-time-grid {\r\n    /* so slats/bg/content/etc positions get scoped within here */\r\n    position: relative;\r\n    z-index: 1; }\r\n  \r\n  .fc-time-grid {\r\n    min-height: 100%;\r\n    /* so if height setting is 'auto', .fc-bg stretches to fill height */ }\r\n  \r\n  .fc-time-grid table {\r\n    /* don't put outer borders on slats/bg/content/etc */\r\n    border: 0 hidden transparent; }\r\n  \r\n  .fc-time-grid > .fc-bg {\r\n    z-index: 1; }\r\n  \r\n  .fc-time-grid .fc-slats,\r\n  .fc-time-grid > hr {\r\n    /* the <hr> AgendaView injects when grid is shorter than scroller */\r\n    position: relative;\r\n    z-index: 2; }\r\n  \r\n  .fc-time-grid .fc-content-col {\r\n    position: relative;\r\n    /* because now-indicator lives directly inside */ }\r\n  \r\n  .fc-time-grid .fc-content-skeleton {\r\n    position: absolute;\r\n    z-index: 3;\r\n    top: 0;\r\n    left: 0;\r\n    right: 0; }\r\n  \r\n  /* divs within a cell within the fc-content-skeleton */\r\n  .fc-time-grid .fc-business-container {\r\n    position: relative;\r\n    z-index: 1; }\r\n  \r\n  .fc-time-grid .fc-bgevent-container {\r\n    position: relative;\r\n    z-index: 2; }\r\n  \r\n  .fc-time-grid .fc-highlight-container {\r\n    position: relative;\r\n    z-index: 3; }\r\n  \r\n  .fc-time-grid .fc-event-container {\r\n    position: relative;\r\n    z-index: 4; }\r\n  \r\n  .fc-time-grid .fc-now-indicator-line {\r\n    z-index: 5; }\r\n  \r\n  .fc-time-grid .fc-helper-container {\r\n    /* also is fc-event-container */\r\n    position: relative;\r\n    z-index: 6; }\r\n  \r\n  /* TimeGrid Slats (lines that run horizontally)\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-time-grid .fc-slats td {\r\n    height: 1.5em;\r\n    border-bottom: 0;\r\n    /* each cell is responsible for its top border */ }\r\n  \r\n  .fc-time-grid .fc-slats .fc-minor td {\r\n    border-top-style: dotted; }\r\n  \r\n  /* TimeGrid Highlighting Slots\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-time-grid .fc-highlight-container {\r\n    /* a div within a cell within the fc-highlight-skeleton */\r\n    position: relative;\r\n    /* scopes the left/right of the fc-highlight to be in the column */ }\r\n  \r\n  .fc-time-grid .fc-highlight {\r\n    position: absolute;\r\n    left: 0;\r\n    right: 0;\r\n    /* top and bottom will be in by JS */ }\r\n  \r\n  /* TimeGrid Event Containment\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-ltr .fc-time-grid .fc-event-container {\r\n    /* space on the sides of events for LTR (default) */\r\n    margin: 0 2.5% 0 2px; }\r\n  \r\n  .fc-rtl .fc-time-grid .fc-event-container {\r\n    /* space on the sides of events for RTL */\r\n    margin: 0 2px 0 2.5%; }\r\n  \r\n  .fc-time-grid .fc-event,\r\n  .fc-time-grid .fc-bgevent {\r\n    position: absolute;\r\n    z-index: 1;\r\n    /* scope inner z-index's */ }\r\n  \r\n  .fc-time-grid .fc-bgevent {\r\n    /* background events always span full width */\r\n    left: 0;\r\n    right: 0; }\r\n  \r\n  /* Generic Vertical Event\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-v-event.fc-not-start {\r\n    /* events that are continuing from another day */\r\n    /* replace space made by the top border with padding */\r\n    border-top-width: 0;\r\n    padding-top: 1px;\r\n    /* remove top rounded corners */\r\n    border-top-left-radius: 0;\r\n    border-top-right-radius: 0; }\r\n  \r\n  .fc-v-event.fc-not-end {\r\n    /* replace space made by the top border with padding */\r\n    border-bottom-width: 0;\r\n    padding-bottom: 1px;\r\n    /* remove bottom rounded corners */\r\n    border-bottom-left-radius: 0;\r\n    border-bottom-right-radius: 0; }\r\n  \r\n  /* TimeGrid Event Styling\r\n  ----------------------------------------------------------------------------------------------------\r\n  We use the full \"fc-time-grid-event\" class instead of using descendants because the event won't\r\n  be a descendant of the grid when it is being dragged.\r\n  */\r\n  .fc-time-grid-event {\r\n    overflow: hidden;\r\n    /* don't let the bg flow over rounded corners */ }\r\n  \r\n  .fc-time-grid-event.fc-selected {\r\n    /* need to allow touch resizers to extend outside event's bounding box */\r\n    /* common fc-selected styles hide the fc-bg, so don't need this anyway */\r\n    overflow: visible; }\r\n  \r\n  .fc-time-grid-event.fc-selected .fc-bg {\r\n    display: none;\r\n    /* hide semi-white background, to appear darker */ }\r\n  \r\n  .fc-time-grid-event .fc-content {\r\n    overflow: hidden;\r\n    /* for when .fc-selected */ }\r\n  \r\n  .fc-time-grid-event .fc-time,\r\n  .fc-time-grid-event .fc-title {\r\n    padding: 0 1px; }\r\n  \r\n  .fc-time-grid-event .fc-time {\r\n    font-size: .85em;\r\n    white-space: nowrap; }\r\n  \r\n  /* short mode, where time and title are on the same line */\r\n  .fc-time-grid-event.fc-short .fc-content {\r\n    /* don't wrap to second line (now that contents will be inline) */\r\n    white-space: nowrap; }\r\n  \r\n  .fc-time-grid-event.fc-short .fc-time,\r\n  .fc-time-grid-event.fc-short .fc-title {\r\n    /* put the time and title on the same line */\r\n    display: inline-block;\r\n    vertical-align: top; }\r\n  \r\n  .fc-time-grid-event.fc-short .fc-time span {\r\n    display: none;\r\n    /* don't display the full time text... */ }\r\n  \r\n  .fc-time-grid-event.fc-short .fc-time:before {\r\n    content: attr(data-start);\r\n    /* ...instead, display only the start time */ }\r\n  \r\n  .fc-time-grid-event.fc-short .fc-time:after {\r\n    content: \"\\A0-\\A0\";\r\n    /* seperate with a dash, wrapped in nbsp's */ }\r\n  \r\n  .fc-time-grid-event.fc-short .fc-title {\r\n    font-size: .85em;\r\n    /* make the title text the same size as the time */\r\n    padding: 0;\r\n    /* undo padding from above */ }\r\n  \r\n  /* resizer (cursor device) */\r\n  .fc-time-grid-event.fc-allow-mouse-resize .fc-resizer {\r\n    left: 0;\r\n    right: 0;\r\n    bottom: 0;\r\n    height: 8px;\r\n    overflow: hidden;\r\n    line-height: 8px;\r\n    font-size: 11px;\r\n    font-family: monospace;\r\n    text-align: center;\r\n    cursor: s-resize; }\r\n  \r\n  .fc-time-grid-event.fc-allow-mouse-resize .fc-resizer:after {\r\n    content: \"=\"; }\r\n  \r\n  /* resizer (touch device) */\r\n  .fc-time-grid-event.fc-selected .fc-resizer {\r\n    /* 10x10 dot */\r\n    border-radius: 5px;\r\n    border-width: 1px;\r\n    width: 8px;\r\n    height: 8px;\r\n    border-style: solid;\r\n    border-color: inherit;\r\n    background: #fff;\r\n    /* horizontally center */\r\n    left: 50%;\r\n    margin-left: -5px;\r\n    /* center on the bottom edge */\r\n    bottom: -5px; }\r\n  \r\n  /* Now Indicator\r\n  --------------------------------------------------------------------------------------------------*/\r\n  .fc-time-grid .fc-now-indicator-line {\r\n    border-top-width: 1px;\r\n    left: 0;\r\n    right: 0; }\r\n  \r\n  /* arrow on axis */\r\n  .fc-time-grid .fc-now-indicator-arrow {\r\n    margin-top: -5px;\r\n    /* vertically center on top coordinate */ }\r\n  \r\n  .fc-ltr .fc-time-grid .fc-now-indicator-arrow {\r\n    left: 0;\r\n    /* triangle pointing right... */\r\n    border-width: 5px 0 5px 6px;\r\n    border-top-color: transparent;\r\n    border-bottom-color: transparent; }\r\n  \r\n  .fc-rtl .fc-time-grid .fc-now-indicator-arrow {\r\n    right: 0;\r\n    /* triangle pointing left... */\r\n    border-width: 5px 6px 5px 0;\r\n    border-top-color: transparent;\r\n    border-bottom-color: transparent; }\r\n  \r\n  /* List View\r\n  --------------------------------------------------------------------------------------------------*/\r\n  /* possibly reusable */\r\n  .fc-event-dot {\r\n    display: inline-block;\r\n    width: 10px;\r\n    height: 10px;\r\n    border-radius: 5px; }\r\n  \r\n  /* view wrapper */\r\n  .fc-rtl .fc-list-view {\r\n    direction: rtl;\r\n    /* unlike core views, leverage browser RTL */ }\r\n  \r\n  .fc-list-view {\r\n    border-width: 1px;\r\n    border-style: solid; }\r\n  \r\n  /* table resets */\r\n  .fc .fc-list-table {\r\n    table-layout: auto;\r\n    /* for shrinkwrapping cell content */ }\r\n  \r\n  .fc-list-table td {\r\n    border-width: 1px 0 0;\r\n    padding: 8px 14px; }\r\n  \r\n  .fc-list-table tr:first-child td {\r\n    border-top-width: 0; }\r\n  \r\n  /* day headings with the list */\r\n  .fc-list-heading {\r\n    border-bottom-width: 1px; }\r\n  \r\n  .fc-list-heading td {\r\n    font-weight: bold; }\r\n  \r\n  .fc-ltr .fc-list-heading-main {\r\n    float: left; }\r\n  \r\n  .fc-ltr .fc-list-heading-alt {\r\n    float: right; }\r\n  \r\n  .fc-rtl .fc-list-heading-main {\r\n    float: right; }\r\n  \r\n  .fc-rtl .fc-list-heading-alt {\r\n    float: left; }\r\n  \r\n  /* event list items */\r\n  .fc-list-item.fc-has-url {\r\n    cursor: pointer;\r\n    /* whole row will be clickable */ }\r\n  \r\n  .fc-list-item-marker,\r\n  .fc-list-item-time {\r\n    white-space: nowrap;\r\n    width: 1px; }\r\n  \r\n  /* make the dot closer to the event title */\r\n  .fc-ltr .fc-list-item-marker {\r\n    padding-right: 0; }\r\n  \r\n  .fc-rtl .fc-list-item-marker {\r\n    padding-left: 0; }\r\n  \r\n  .fc-list-item-title a {\r\n    /* every event title cell has an <a> tag */\r\n    text-decoration: none;\r\n    color: inherit; }\r\n  \r\n  .fc-list-item-title a[href]:hover {\r\n    /* hover effect only on titles with hrefs */\r\n    text-decoration: underline; }\r\n  \r\n  /* message when no events */\r\n  .fc-list-empty-wrap2 {\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    right: 0;\r\n    bottom: 0; }\r\n  \r\n  .fc-list-empty-wrap1 {\r\n    width: 100%;\r\n    height: 100%;\r\n    display: table; }\r\n  \r\n  .fc-list-empty {\r\n    display: table-cell;\r\n    vertical-align: middle;\r\n    text-align: center; }\r\n  \r\n  .fc-unthemed .fc-list-empty {\r\n    /* theme will provide own background */\r\n    background-color: #eee; }\r\n  ", "2023-01-05 17:28:07.021000", "Full Calendar Styling Sheet", "Calendar Styling", "", 30, 3, "capacity-planning", 0], [21, "_binary \u0001", "{% Script Util %}\r\n\r\n//Filter Variables\r\nvar dailyCapacityParam = $NUM{Daily_Capacity};\r\n\r\nvar parameterCatName = \"$TEXT{Calendar_Category|%}\";\r\nparameterCatName = \"\\'\" + parameterCatName.toUpperCase() + \"\\'\";\r\nconsole.log(\"CatName = \" + parameterCatName);\r\n\r\nvar defaultView, parameterDefaultView = \"$LIST{Default_View|^Week,Month,Day}\";\r\nswitch (parameterDefaultView) {\r\n    case \"Month\":\r\n        defaultView = \"month\";\r\n        break;\r\n    case \"Week\":\r\n        defaultView = \"agendaWeek\";\r\n        break;\r\n    case \"Day\":\r\n        defaultView = \"agendaDay\";\r\n        break;\r\n}\r\nvar DailyCapacities = {};\r\nvar calendarDate = moment(\"$DATE{Date|Today}\");\r\n\r\n// CHANGE WOITEM DATE SCHEDULED API CALL\r\nfunction updateWOItem(event, view) {\r\n    let eventStart = moment(event.start).format('YYYY-MM-DD[T]HH:mm:ss');\r\n    let eventEnd = moment(event.end).format('YYYY-MM-DD[T]HH:mm:ss');\r\n    if (eventStart == null) {\r\n        return \"No Start Date Found\";\r\n    }\r\n    console.log(\"\\r\\nEvent Start = \" + eventStart + \" Event End = \" + eventEnd);\r\n    let WONum = {GetWorkOrderRq: {WorkOrderNumber: event.wonum}};\r\n    console.log(\"\\r\\nEvent WO Num = \" + WONum);\r\n    let WOAPIObject = JSON.parse(runApiRequest('GetWorkOrderRq', JSON.stringify(WONum)));\r\n\r\n    if (WOAPIObject.statusCode == 1001) {\r\n        console.log(\"\\r\\nUnable to parse API request. WO Num = \" + WONum);\r\n        return WOAPIObject;\r\n    }\r\n    else {\r\n        let WO = WOAPIObject.GetWorkOrderRs.WO;\r\n\r\n        //              CHECK TO SEE IF THE EVENT HAS AN END DATE\r\n        if (!moment(event.end).isValid()) {\r\n            // CHANGE EACH WO ITEM DATE SCHEDULED \r\n            for (i = 0; i < WO.WOItems; i++) {\r\n                WO.WOItems[i].DateScheduled = eventStart;\r\n            }\r\n            // CHANGE WO DATE SCHEDULED/DATE SCHEDULED TO START\r\n            console.log(\"Event end was null\");\r\n            WO.DateScheduled = eventStart;\r\n            WO.DateScheduledToStart = eventStart;\r\n        }\r\n        else {\r\n            console.log(\"Event end was not null\");\r\n            for (i = 0; i < WO.WOItems; i++) {\r\n                WO.WOItems[i].DateScheduled = eventStart;\r\n            }\r\n\r\n            WO.DateScheduled = eventEnd;\r\n            WO.DateScheduledToStart = eventStart;\r\n        }\r\n\r\n        //                  FORMAT REQUEST OBJECT\r\n        let WONewDate = {SaveWorkOrderRq: {'WO': WO}};\r\n\r\n        //              UPDATE THE WORK ORDER AND WO ITEMS\r\n        let SaveWorkOrderRs = runApiRequest(\"SaveWorkOrderRq\", JSON.stringify(WONewDate));\r\n\r\n        if (SaveWorkOrderRs.statusCode == 1000) {\r\n            console.log(\"Work Order \" + event.wonum + \" has been successfully updated to start date and end date \" + eventStart);\r\n        }\r\n        else {\r\n            console.log(\"SaveWorkOrderRs = \\r\\n\" + JSON.stringify(SaveWorkOrderRs));\r\n        }\r\n\r\n    }\r\n}\r\n\r\nvar query = \"SELECT bom.num AS bomnum,mo.id AS moid, mo.num AS monum, wo.num AS wonum, moitem.description AS moitemdesc,\"\r\n    + \"\\r\\nCOALESCE(bom.estimatedDuration,0) * COALESCE(wo.qtyTarget,0) AS estimatedDuration, COALESCE(wo.datescheduled,moitem.datescheduled) AS datescheduled, COALESCE(wo.datescheduledtostart,moitem.datescheduledtostart) datescheduledtostart, calcat.color AS catcolor,\"\r\n    + \"\\r\\ncalcat.name AS catname, wo.id AS woid\"\r\n    + \"\\r\\n\"\r\n    + \"\\r\\nFROM moitem\"\r\n    + \"\\r\\nLEFT JOIN mo ON moitem.moid = mo.id\"\r\n    + \"\\r\\nLEFT JOIN wo ON wo.moitemid = moitem.id\"\r\n    + \"\\r\\nLEFT JOIN bom ON moitem.bomid = bom.id\"\r\n    + \"\\r\\nLEFT JOIN calcategory AS calcat ON wo.calcategoryid = calcat.id\"\r\n    + \"\\r\\n\"\r\n    + \"\\r\\nWHERE moitem.typeid = 50\"\r\n    + \"\\r\\nAND wo.num IS NOT NULL\"\r\n    + \"\\r\\nAND moitem.statusid IN (10,20,30,40)\"\r\n    + \"\\r\\nAND IF(\" + parameterCatName + \" = '%', 1=1,UPPER(calcat.name) LIKE \" + parameterCatName + \")\"\r\n    + \"\\r\\nORDER BY moitem.datescheduled\";\r\n\r\nvar moitems = JSON.parse(runQuery(query));\r\n\r\nvar events = [];\r\nvar dayTotals = {};\r\nvar currentView = \"Month\";\r\nvar clickTimer, doubleClick;\r\nvar tUOM;\r\nvar tUOMSelection = \"$LIST{UOM|hr,min}\";\r\nswitch (tUOMSelection) {\r\n    case \"hr\":\r\n        tUOM = 60;\r\n        break;\r\n    case \"min\":\r\n        tUOM = 1;\r\n        break;\r\n}\r\n\r\nvar showBOM = $CHECK{Show_Work_Order_Description_in_Title|false};\r\n\r\n\r\nfor (i = 0; i < moitems.length; i++) {\r\n    let duration = moitems[i].estimatedduration / tUOM;\r\n\r\n//  FORMAT THE TITLE OF THE EVENT AND THEN ADD THE EVENT TO THE LIST\r\n    let title;\r\n    if (showBOM) {\r\n        title = duration + \" - \" + moitems[i].wonum + \" : \" + moitems[i].bomnum;\r\n    }\r\n    else {\r\n        title = duration + \" - \" + moitems[i].wonum;\r\n    }\r\n    let catColor = \"#\" + moitems[i].catcolor;\r\n    let event = {\r\n        'id': moitems[i].woid,\r\n        'title': title,\r\n        'start': moitems[i].datescheduled,\r\n        'end': moitems[i].datescheduled,\r\n        allDay: true,\r\n        monum: moitems[i].monum,\r\n        wonum: moitems[i].wonum,\r\n        \"duration\": duration,\r\n        \"color\": catColor\r\n    };\r\n    events.push(event);\r\n\r\n//  CALCULATE DAILY DURATION TOTALS    \r\n    let currentDay = moment(moitems[i].datescheduled).toDate();\r\n    currentDay = moment(currentDay).format('YYYY-MM-DD');\r\n\r\n    if (dayTotals[currentDay] != null) {\r\n        dayTotals[currentDay] += duration;\r\n    }\r\n    else {\r\n        dayTotals[currentDay] = duration;\r\n    }\r\n}\r\n\r\n// GENERATE THE ACTUAL CALENDAR\r\n$(function () {\r\n    $('#calendar').fullCalendar({\r\n            header: {\r\n                left: 'prev,next today',\r\n                center: 'title',\r\n                right: 'month,agendaWeek,agendaDay'\r\n            },\r\n            eventStartEditable: true,\r\n            eventLimit: true, // when too many events in a day, show the popover\r\n            events: events,\r\n            defaultView: defaultView,\r\n            defaultDate: calendarDate,\r\n\r\n//    THIS IS THE FUNCTION THAT WILL RUN FOR EACH DAY EVERY TIME IT NEEDS TO RENDER A DAY ex.Switching views, or if they drag and drop an item\r\n            dayRender: function (date, cell, view) {\r\n\r\n//        SET MY INDEX AND MY JQUERY OBJECT\r\n                var ddate = moment(date).format('YYYY-MM-DD');\r\n                var dayNumber = \"*[data-date=\\\"\" + ddate + \"\\\"] span\";\r\n                let dailyCapacity;\r\n                if (UTIL.objContains(DailyCapacities, ddate)) {\r\n                    dailyCapacity = DailyCapacities[ddate];\r\n                    console.log(\"\\r\\nUsed capacity from object \" + DailyCapacities[ddate]);\r\n                }\r\n                else {\r\n                    dailyCapacity = dailyCapacityParam;\r\n                    console.log(\"\\r\\nUsed Param Capacity \" + dailyCapacityParam);\r\n                }\r\n//        CHECK TO SEE IF THE DATE HAS A DURATION. IF IT DOES THEN CHANGE THE HEADER\r\n                var idx = cell.index() + 1;\r\n                let viewHeader;\r\n\r\n                $(dayNumber).html(function (i, origText) {\r\n                    switch (view.name) {\r\n                        case \"month\":\r\n                            viewHeader = \"<span style=float:center; text-align = center>\" + (dayTotals[ddate] || \"0\") + \"/ \" + dailyCapacity + \"&nbsp&nbsp&nbsp&nbsp</span><span style = font-size:16px><b>\" + origText + \"</b></span>\";\r\n                            break;\r\n                        case \"agendaWeek\":\r\n                            viewHeader = \"<span style=text-align:center;font-size:16px><b>&nbsp\" + origText + \"</b></span><br><span style=float:center; text-align = center>\" + (dayTotals[ddate] || \"0\") + \"/ \" + dailyCapacity + \"\\r\\n</span>\";\r\n                            break;\r\n                        case \"agendaDay\":\r\n                            viewHeader = \"<span style=float:center; text-align = center>\" + (dayTotals[ddate] || \"0\") + \"/ \" + dailyCapacity + \" \" + origText + \"</b></span>\";\r\n                            break;\r\n                    }\r\n\r\n                    return viewHeader;\r\n                })\r\n\r\n//        CHECK TO SEE IF THE DAYS TOTAL DURATION IS OVER THE SET MAX. IF IT IS THEN MAKE THE BACKGROUND RED\r\n                if (dayTotals[ddate] > dailyCapacity) {\r\n                    idx = cell.index() + 1;\r\n                    cell.css(\"background-color\", \"#ff3333\");\r\n                    $(\".fc-time-grid .fc-bg table tbody tr td:nth-child(\" + idx + \")\").css(\"background-color\", \"#ff9999\");\r\n                }\r\n\r\n                let numberInputObj = \"#\" + ddate\r\n                $(numberInputObj).on('keyup mouseup', function () {\r\n                    let num = $(this).val();\r\n                    let day = $(this).attr('id');\r\n                    DailyCapacities[day] = num;\r\n                    console.log(\"\\r\\nDaily Capacity Object = \" + JSON.stringify(DailyCapacities));\r\n                    $('#calendar').fullCalendar('prev');\r\n                    $('#calendar').fullCalendar('next');\r\n                });\r\n            },\r\n\r\n            eventClick: function (event) {\r\n                let monum = event.monum;\r\n                openModule(\"Manufacture Order\", monum);\r\n            },\r\n\r\n            eventMouseover: function (event) {\r\n                let wonum = event.wonum;\r\n                let rgquery = \"SELECT woitem.sortid, CONCAT(part.num, ' - ', part.description) AS woitempart, woitem.qtytarget AS rgqty, wo.num AS wonum, moitem.description AS woitemdescription, COALESCE(calcat.name,'') AS calcategory \"\r\n                    + \"\\r\\n\"\r\n                    + \"\\r\\n FROM woitem\"\r\n                    + \"\\r\\n JOIN part ON part.id = woitem.partid AND woitem.typeid = 20\"\r\n                    + \"\\r\\n JOIN wo ON woitem.woid = wo.id\"\r\n                    + \"\\r\\n LEFT OUTER JOIN moitem ON wo.moitemid = moitem.id\"\r\n                    + \"\\r\\nLEFT JOIN calcategory AS calcat ON wo.calcategoryid = calcat.id\"\r\n                    + \"\\r\\n\"\r\n                    + \"\\r\\n WHERE wo.num LIKE \" + JSON.stringify(wonum)\r\n                    + \"\\r\\n ORDER BY woitem.sortid\";\r\n\r\n                let woitems = JSON.parse(runQuery(rgquery));\r\n                let headers = ['Part', 'Qty Needed'];\r\n                let dontShow = [];\r\n                let title = woitems[0].wonum + \" - \" + woitems[0].woitemdescription + \"\\r\\n\" + woitems[0].calcategory;\r\n                for (let i = 0; i < woitems.length; i++) {\r\n                    console.log(\"deleted wonum = \" + delete woitems[i].wonum);\r\n                    console.log(\"deleted woitemdescription = \" + delete woitems[i].woitemdescription);\r\n                    console.log(\"deleted calcategory = \" + delete woitems[i].calcategory);\r\n                    delete woitems[i].sortid;\r\n                }\r\n                tooltip = '<div class=\"tooltiptopicevent\" style=\"width:auto;height:auto;background:white;position:absolute;z-index:10001;padding:10px 10px 10px 10px ;  line-height: 200%;\">'\r\n                    + \"<table class='table'><thead><td style=text-align:center><h3>\" + title + \"</h3></td></thead> <tbody border=1 id=\\\"2ltip\\\"> \" + UTIL.makeTable(woitems, headers, dontShow) + \"</tbody></table>\";\r\n\r\n\r\n                $(\"body\").append(tooltip);\r\n                $(this).mouseover(function (e) {\r\n                    $(this).css('z-index', 10000);\r\n                    $('.tooltiptopicevent').fadeIn('500');\r\n                    $('.tooltiptopicevent').fadeTo('10', 1.9);\r\n                }).mousemove(function (e) {\r\n                    $('.tooltiptopicevent').css('top', e.pageY + 10);\r\n                    $('.tooltiptopicevent').css('left', e.pageX + 20);\r\n                }).mouseleave(function (e) {\r\n                    $('.tooltiptopicevent').remove();\r\n                });\r\n            },\r\n\r\n            eventDrop: function (event, delta, revertFunc, jsEvent, ui, view) {\r\n                updateWOItem(event, view);\r\n\r\n                //          CALCULATE NEW AND OLD DATES\r\n                let newDate = moment(event.start).format('YYYY-MM-DD');\r\n                let oldDate = event.start.subtract(delta).format('YYYY-MM-DD');\r\n                console.log(\"\\r\\nNew Date: \" + newDate + \"\\r\\nOld Date: \" + oldDate);\r\n\r\n                //          ADD THE DURATION TO THE NEW DAY'S TOTAL. HAVE TO CHECK TO SEE IF THE DAY ALREADY EXISTS            \r\n                if (UTIL.objContains(dayTotals, newDate)) {\r\n                    dayTotals[newDate] += event.duration;\r\n                }\r\n                else {\r\n                    dayTotals[newDate] = event.duration;\r\n                }\r\n                //          SUBTRACT THE DURATION FROM THE OLD DAY. THEN CHECK TO SEE IF THE NEW TOTAL IS 0. IF IT IS THEN DELETE IT            \r\n                dayTotals[oldDate] -= event.duration;\r\n                if (dayTotals[oldDate] == 0) {\r\n                    delete dayTotals[oldDate];\r\n                }\r\n                //          UNFORTUNATELY IT ISN'T POSSIBLE TO JUST RELOAD A SINGLE DAY. SO THIS RELOADS THE WHOLE CALENDAR AS IF YOU PRESSED THE PREV AND NEXT BUTTONS \r\n                $('#calendar').fullCalendar('prev');\r\n                $('#calendar').fullCalendar('next');\r\n            },\r\n\r\n            eventResize: function (event, jsEvent, ui, view) {\r\n                updateWOItem(event, view);\r\n            },\r\n\r\n            dayClick: function (date, jsEvent, view) {\r\n                // GET THE BEGINNING AND END OF WEEK FOR WEEK VIEW\r\n                var singleClick = date.format('YYYY-MM-DD HH:mm:ss');\r\n\r\n                if (doubleClick == singleClick) {\r\n                    switch (view.name) {\r\n                        case \"month\":\r\n                            $('#calendar').fullCalendar('gotoDate', date);\r\n                            $('#calendar').fullCalendar('changeView', 'agendaWeek');\r\n                            break;\r\n                        case \"agendaWeek\":\r\n                            $('#calendar').fullCalendar('changeView', 'agendaDay', date);\r\n                            break;\r\n                    }\r\n                    doubleClick = null;\r\n                } else {\r\n                    doubleClick = date.format('YYYY-MM-DD HH:mm:ss');\r\n                    clearInterval(clickTimer);\r\n                    clickTimer = setInterval(function () {\r\n                        doubleClick = null;\r\n                        clearInterval(clickTimer);\r\n                        console.log(\"\\r\\nNot Double Click\")\r\n                    }, 500);\r\n                }\r\n            }\r\n        }\r\n    );\r\n})", "2023-01-05 17:28:07.021000", "The script for the capacity planning BisKit", "Capacity Planning", "", 20, 3, "capacity-planning", 0], [22, "_binary \u0001", "<head>\r\n   <script\r\n      src=\"https://code.jquery.com/jquery-3.4.1.slim.min.js\"\r\n      integrity=\"sha256-pasqAKBDmFT4eHoN2ndd6lN370kFiGUFyTiUHWhU7k8=\"\r\n      crossorigin=\"anonymous\"\r\n   ></script>\r\n   <link\r\n      rel=\"stylesheet\"\r\n      href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css\"\r\n      integrity=\"sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm\"\r\n      crossorigin=\"anonymous\"\r\n   />\r\n   <script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js\"></script>\r\n   <style>\r\n   {% Style Category_Capacity_Planning %}\r\n   </style>\r\n</head>\r\n<body>\r\n   <div id=\"button-header\" class=\"wrapper\">\r\n      <button id=\"prev-button\" class=\"previous button\">Prev</button>\r\n      <button id=\"next-button\" class=\"next button\">Next</button>\r\n   </div>\r\n   <div id=\"table-wrapper\" class=\"wrapper\">\r\n      <table id=\"schedule-table\" class=\"table table-bordered\"></table>\r\n   </div>\r\n</body>\r\n<script>\r\n{% Script Category_Capacity_Planning %}\r\n</script>\r\n", "2023-01-05 17:28:07.037000", "Capacity planning separated out by calendar category", "Category Capacity Planning", "", 10, 1, "category-capacity-planning", 1], [23, "_binary \u0001", "      :root {\r\n   --light: 80;\r\n   --threshold: 60;\r\n   --border-threshold: 80;\r\n}\r\ntd.day:not(.busy) {\r\n   padding-bottom: 40px !important;\r\n}\r\ntd {\r\n   padding: 8px !important;\r\n}\r\ndiv.event {\r\n   min-height: 40px;\r\n   margin-left: 5px;\r\n   margin-right: 5px;\r\n   padding: 8px;\r\n   --switch: calc((var(--light) - var(--threshold)) * -100%);\r\n   color: hsl(0, 0%, var(--switch));\r\n   --border-light: calc(var(--light) * 0.7%);\r\n   --border-alpha: calc((var(--light) - var(--border-threshold)) * 10);\r\n   border: 0.1em solid\r\n      hsla(\r\n         var(--hue),\r\n         calc(var(--sat) * 1%),\r\n         var(--border-light),\r\n         var(--border-alpha)\r\n      );\r\n}\r\ndiv.event-wrapper {\r\n   padding: 8px;\r\n}\r\ntd.bg-danger {\r\n   color: white !important;\r\n}\r\ndiv.capacity {\r\n   border-bottom: 1px solid black;\r\n}\r\ndiv.wrapper {\r\n   overflow: auto;\r\n   width: 100%;\r\n}\r\n\r\ndiv.capacity-modal {\r\n   position: absolute;\r\n   display: none;\r\n   width: 150px;\r\n   height: fit-content;\r\n   padding: 8px;\r\n   text-align: right;\r\n}\r\n.dropdown-content {\r\n   position: relative;\r\n   right: 0;\r\n   background-color: #f1f1f1;\r\n   box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);\r\n   z-index: 9999;\r\n}\r\n.capacity-input {\r\n   width: 40px;\r\n}\r\n.resizer {\r\n   width: 5px;\r\n   min-height: 40px;\r\n   height: 100%;\r\n   background: transparent;\r\n   position: relative;\r\n   display: inline-block;\r\n}\r\n.resizer.left {\r\n   float: left;\r\n   cursor: w-resize; /*resizer cursor*/\r\n}\r\n.resizer.right {\r\n   float: right;\r\n   cursor: e-resize;\r\n}\r\n#button-header {\r\n   margin-bottom: 10px;\r\n   text-align: right;\r\n}\r\nbody {\r\n   margin: 15px;\r\n   font-family: 'Open Sans', sans-serif;\r\n}\r\nthead {\r\n   background-color: #eaeaea;\r\n}\r\n.capacity-button {\r\n   display: flex;\r\n}", "2023-01-05 17:28:07.037000", "Capacity planning separated out by calendar category", "Category Capacity Planning", "", 30, 1, "category-capacity-planning", 0], [24, "_binary \u0001", "   let capacities;\r\nconst daysInWeek = 7;\r\nconst tableId = 'schedule-table';\r\nconst HeaderDateFormat = 'dddd MMM-D';\r\nconst NameOfResource = 'Machine';\r\nlet currentViewWeek = moment().startOf('day');\r\nlet getEventData = (momentDate) => {\r\n   console.groupCollapsed('getEventData');\r\n   let queryDate = moment(momentDate);\r\n   const QUERY = `SELECT CONCAT('WO#:',wo.num) AS eventName,\r\n                wo.num AS eventNameRaw,\r\n                wo.note AS eventDescription,\r\n                DATE(wo.dateScheduledToStart) AS startDate,\r\n                DATE(wo.dateScheduled) AS endDate,\r\n                COALESCE(calcategory.id,0) AS resourceId,\r\n                CONCAT('#',COALESCE(REPLACE(calcategory.color,'x',''),'A9A9A9')) AS color,\r\n                (COALESCE(bom.estimatedduration,0) / 60) * wo.qtyTarget AS estimatedHours,\r\n                ROUND(((COALESCE(bom.estimatedduration,0) / 60) * wo.qtyTarget) / (DATEDIFF(wo.dateScheduled,wo.dateScheduledToStart) + 1),2) AS estimatedDailyHours,\r\n                (DATEDIFF(wo.dateScheduled,wo.dateScheduledToStart) + 1) AS datediff\r\n\r\n                FROM wo\r\n                LEFT JOIN calcategory ON wo.calcategoryid = calcategory.id\r\n                LEFT JOIN moitem ON wo.moitemid = moitem.id\r\n                LEFT JOIN bom ON moitem.bomid = bom.id\r\n                WHERE wo.statusid < 40\r\n                AND (YEARWEEK(wo.dateScheduledToStart) = YEARWEEK('${queryDate.format(\r\n                   'YYYY-MM-DD'\r\n                )}') OR YEARWEEK(wo.dateScheduled) = YEARWEEK('${queryDate.format(\r\n      'YYYY-MM-DD'\r\n   )}'))`;\r\n   console.log('Query', QUERY);\r\n   let events = JSON.parse(runQuery(QUERY));\r\n   if (events.length > 0) {\r\n      console.log('events exist', events);\r\n   } else {\r\n      console.log(\r\n         `No events found this week: ${queryDate.format('YYYY-MM-DD')}`\r\n      );\r\n   }\r\n   console.groupEnd('getEventData');\r\n   return events;\r\n};\r\nfunction getOffset(el) {\r\n   var _x = 0;\r\n   var _y = 0;\r\n   while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {\r\n      _x += el.offsetLeft - el.scrollLeft;\r\n      _y += el.offsetTop - el.scrollTop;\r\n      el = el.offsetParent;\r\n   }\r\n   return { top: _y, left: _x };\r\n}\r\nlet getResources = () => {\r\n   console.groupCollapsed('getResources');\r\n   let QUERY = `SELECT\r\n                    name,\r\n                    id,\r\n                    \"\" AS limits,\r\n                    CONCAT('#',color) AS color\r\n\r\n                    FROM calcategory\r\n                    ORDER BY id DESC`;\r\n   console.log('Query', QUERY);\r\n\r\n   // ADD LOAD REPORT DATA HERE ONCE THE REPORT IS FUNCTIONAL. ALSO ADD THE ABILITY TO EASILY SWITCH BACK TO THIS TEST DATA\r\n   // saveReportData('');\r\n   capacities = loadReportData();\r\n   if (!capacities) {\r\n      capacities = [];\r\n      console.log('capacities was blank');\r\n   } else {\r\n      capacities = JSON.parse(capacities);\r\n      console.log('parsed capacities object', capacities);\r\n      capacities = capacities[0].capacities;\r\n      console.log('capacities was found and parsed', capacities);\r\n   }\r\n   // capacities = [\r\n   //    { resourceId: 102, defaultCapacity: [8, 7, 6, 5, 4, 3, 2] },\r\n   //    { resourceId: 101, defaultCapacity: [1, 2, 3, 4, 5, 6, 7] },\r\n   // ];\r\n   let resources = [\r\n      {\r\n         name: 'No Resource Assigned',\r\n         id: '0',\r\n         limits: [0, 0, 0, 0, 0, 0, 0],\r\n         color: 'grey',\r\n      },\r\n   ];\r\n   let results = JSON.parse(runQuery(QUERY));\r\n   console.log('Query Resluts', results);\r\n   if (!!resources) {\r\n      resources = resources.concat(results);\r\n   }\r\n\r\n   if (resources.length > 0) {\r\n      for (resource of resources) {\r\n         for (cap of capacities) {\r\n            if (cap.id == resource.id) {\r\n               resource.limits = cap.limits;\r\n               console.log(\r\n                  'default capacities found for resource',\r\n                  resource.limits\r\n               );\r\n            }\r\n         }\r\n         if (!resource.limits) {\r\n            console.log(\r\n               'No capacity settings found for this resource. Setting capacities to default'\r\n            );\r\n            resource.limits = [8, 8, 8, 8, 8, 8, 8];\r\n         }\r\n      }\r\n      console.groupCollapsed('resourcesResults');\r\n      console.log('resources', resources);\r\n      console.groupEnd('resourcesResults');\r\n   } else {\r\n      console.error('No Resources Found');\r\n   }\r\n   console.groupEnd('getResources');\r\n   return resources;\r\n};\r\nconst resources = getResources();\r\n\r\nlet calcUsage = () => {\r\n   console.groupCollapsed('calcUsage');\r\n   let timestamp = Date.now();\r\n   for (resource of resources) {\r\n      for (let i = 0; i < daysInWeek; i++) {\r\n         let dayTotal = 0;\r\n         let capacity;\r\n         let days = $(`td.day${i}.${resource.id}.busy`);\r\n         if (days[0]) {\r\n            capacity = days[0].getAttribute('capacity');\r\n         } else {\r\n            console.log('no busy days. removed warning');\r\n            $(`td.day${i}.${resource.id}`).removeClass('bg-danger');\r\n            continue;\r\n         }\r\n         days.children().each((index, cell) => {\r\n            dayTotal += parseInt($(cell).attr('duration'));\r\n         });\r\n         console.log(`day ${i} Total:`, dayTotal, 'capacity:', capacity);\r\n         console.log($(`td.day${i}.${resource.id}`));\r\n         $(`td.day${i}.${resource.id}`).each((index, cell) => {\r\n            if (cell.getAttribute('usage-calculated-ts') == timestamp) {\r\n               return true;\r\n            }\r\n            if (capacity >= dayTotal) {\r\n               console.log('removed warning');\r\n               $(cell).removeClass('bg-danger');\r\n               cell.setAttribute('usage-calculated-ts', timestamp);\r\n            } else {\r\n               console.log('added warning');\r\n               $(cell).addClass('bg-danger');\r\n               cell.setAttribute('usage-calculated-ts', timestamp);\r\n            }\r\n         });\r\n      }\r\n   }\r\n   console.groupEnd('calcUsage');\r\n   return true;\r\n};\r\n\r\nlet createRow = (resourceId) => {\r\n   /* MAYBE I CAN INSERT THE CAPACITY INPUTS AFTER I HAVE ACTUALLY ADDED THE ROW IN THE DOM. JUST LOOP THROUGH MY NUMBER OF DAYS AND ADD A CAPACITY INPUT FOR EACH WITH THE VALUES PULLED FROM DATABASE*/\r\n   console.groupCollapsed('createRow');\r\n   let rowString = '';\r\n   let resource;\r\n   let resourceNameCell = $(`td.resource-name.${resourceId}`);\r\n   let rowCount;\r\n   let rowId = Math.trunc(Math.random() * 1000000);\r\n   let tableElement = document.getElementById(tableId);\r\n   for (let item of resources) {\r\n      if (item.id == resourceId) {\r\n         resource = item;\r\n         break;\r\n      }\r\n   }\r\n   if (!resource) {\r\n      console.log('no resource found with id', resourceId);\r\n      console.groupEnd('createRow');\r\n      return false;\r\n   }\r\n\r\n   //If the resource doesn't exist create a new one\r\n   if (!resourceNameCell.length) {\r\n      console.log(\r\n         `row for resource ${resource.name} does not exist. Adding new resource row`\r\n      );\r\n      rowCount = 2;\r\n      let newTbody = document.createElement('tbody', {\r\n         id: `${resource.id}body`,\r\n         class: resource.id,\r\n         resource: resource.id,\r\n      });\r\n      newTbody.setAttribute('id', `${resource.id}body`);\r\n      newTbody.setAttribute('class', resource.id);\r\n      newTbody.setAttribute('resource', resource.id);\r\n\r\n      let newRow = document.createElement('tr');\r\n      newRow.setAttribute('id', rowId);\r\n      newRow.setAttribute('class', `${resource.id} capacity`);\r\n      newRow.setAttribute('resource', resource.id);\r\n      console.log('newRow', newRow);\r\n      let nameCell = newRow.insertCell();\r\n      nameCell.setAttribute('rowspan', 2);\r\n      nameCell.setAttribute('class', `resource-name ${resource.id}`);\r\n      $(nameCell)\r\n         .append(`<span id=\"${resource.name}\" class=\"resource-name\">${resource.name}</span>\r\n                                    <button\r\n                                        id=\"button-${resource.id}\"\r\n                                        class=capacity-button\r\n                                        onclick=\"showCapSettings(event)\"\r\n                                        resource=\"${resource.id}\">\r\n                                        Adjust Caps\r\n                                    </button>\r\n                                    <div\r\n                                        id=\"capacity-modal-${resource.id}\"\r\n                                        class=\"dropdown-content modal capacity-modal ${resource.id}\"\r\n                                        resource=\"${resource.id}\">\r\n                                    </div>`);\r\n      newTbody.appendChild(newRow);\r\n      console.log('newTbody', newTbody);\r\n      tableElement.appendChild(newTbody);\r\n      for (let i = 0; i < daysInWeek; i++) {\r\n         $(newRow).append(`<td\r\n                            id=\"${i}${resource.id}${rowCount}capacity\"\r\n                            class=\"day${i} ${resource.id} capacity\"\r\n                            resource=\"${resource.id}\"\r\n                            day=\"${i}\"\r\n                            row=\"${rowId}\"\r\n                            capacity=\"${resource.limits[i]}\"\r\n                        >\r\n                            <div class=\"day${i} ${resource.id} capacity\"\r\n                                resource=\"${resource.id}\"\r\n                                day=\"${i}\"\r\n                                row=\"${rowId}\"\r\n                                duration=\"0\">Cap: ${resource.limits[i]} hrs</div>\r\n                        </td>`);\r\n      }\r\n      $(`table#${tableId}`).append(newTbody);\r\n      console.log('created new resource row', $(`tr#${rowId}`));\r\n\r\n      for (let dayOfWeek = 0; dayOfWeek < daysInWeek; dayOfWeek++) {\r\n         let week = moment($('table').attr('date'));\r\n         console.log('name of week', week.day(dayOfWeek).format('dddd'));\r\n         let capacityString = `<label class=\"input-label\">${week\r\n            .day(dayOfWeek)\r\n            .format('dddd')}</label>\r\n                                <input\r\n                                    type=\"number\"\r\n                                    min=\"0\"\r\n                                    value=\"${resource.limits[dayOfWeek]}\"\r\n                                    day=\"${dayOfWeek}\"\r\n                                    resource=\"${resource.id}\"\r\n                                    id=\"day${dayOfWeek}capacity-${\r\n            resource.id\r\n         }\"\r\n                                    class=\"capacity-input\"\r\n                                    onChange=\"capacityChange(event)\">\r\n                                <br>`;\r\n\r\n         $(`#capacity-modal-${resource.id}`).append(capacityString);\r\n      }\r\n      // Add the save button\r\n      $(`#capacity-modal-${resource.id}`).append(\r\n         `<input\r\n                type=\"button\"\r\n                class=\"save\"\r\n                onclick=\"saveCapacities(event)\"\r\n                value=\"Save\"\r\n                resource=\"${resource.id}\"/>`\r\n      );\r\n   }\r\n   // Once the resource row exists, or if it already existed, do this\r\n   let newRow = document.createElement('tr');\r\n   newRow.setAttribute('id', rowId);\r\n   newRow.setAttribute('class', `${resource.id} day`);\r\n   newRow.setAttribute('resource', resource.id);\r\n\r\n   rowCount = $(`tr.${resource.id}`).length + 1;\r\n   console.log('rowCount', rowCount);\r\n   resourceNameCell.attr('rowspan', rowCount);\r\n\r\n   for (let i = 0; i < daysInWeek; i++) {\r\n      $(newRow).append(`<td\r\n                        id=\"${i}${resource.id}${rowCount}\"\r\n                        class=\"day${i} ${resource.id} day\"\r\n                        resource=\"${resource.id}\"\r\n                        day=\"${i}\"\r\n                        row=\"${rowId}\"\r\n                        ondrop=\"moveEvent(event)\"\r\n                        ondragover=\"allowDrop(event)\"\r\n                        capacity=\"${resource.limits[i]}\"></td>`);\r\n   }\r\n   console.log(\r\n      `tbody resourceId:${resourceId}`,\r\n      $(`tbody#${resourceId}body`)\r\n   );\r\n   $(`tbody#${resourceId}body`).append(newRow);\r\n   console.log(\r\n      `added row to existing resource id:${resourceId}`,\r\n      $(`tr#${rowId}`)\r\n   );\r\n   console.groupEnd('createRow');\r\n   return $(`tr#${rowId}`);\r\n};\r\n\r\nlet addEvent = (event) => {\r\n   console.groupCollapsed('addEvent');\r\n   let startDate = moment(event.startdate);\r\n   let visualStartDate = moment(event.startdate).clone();\r\n   let endDate = moment(event.enddate);\r\n   let visualEndDate = moment(event.enddate).clone();\r\n\r\n   // for events that leak into the current week I am viewing\r\n   console.log(\r\n      visualStartDate.week(),\r\n      visualEndDate.week(),\r\n      currentViewWeek.week()\r\n   );\r\n   if (visualStartDate.week() != currentViewWeek.week()) {\r\n      visualStartDate = currentViewWeek.clone().day(0);\r\n   } else if (visualEndDate.week() != currentViewWeek.week()) {\r\n      visualEndDate = currentViewWeek.clone().day(6);\r\n   }\r\n   let startDay = visualStartDate.clone().day();\r\n   let endDay = visualEndDate.clone().day();\r\n   console.log(startDate, visualStartDate, startDay);\r\n   console.log(endDate, visualEndDate, endDay);\r\n\r\n   let resourceId = event.resourceid;\r\n   let resourceRows = $(`tr.${resourceId}.day`);\r\n   let daysInRange = [];\r\n   let busyDaysInRange = [];\r\n   let openRow;\r\n   let allEventDaysCells;\r\n   let eventCell;\r\n   console.log('Start Day: ', startDay, ' End Day: ', endDay);\r\n   for (i = startDay; i <= endDay; i++) {\r\n      daysInRange.push('.day' + i);\r\n      busyDaysInRange.push('.day' + i + '.busy');\r\n   }\r\n   daysInRange = daysInRange.join();\r\n   busyDaysInRange = busyDaysInRange.join();\r\n   resourceRows.each((index, cell) => {\r\n      let rowBusy = false;\r\n      $(cell)\r\n         .children(busyDaysInRange)\r\n         .each((i, c) => {\r\n            rowBusy = true;\r\n            return false;\r\n         });\r\n      if (rowBusy == false) {\r\n         openRow = cell;\r\n         console.log(`Open Row found. row id = ${openRow.id}`);\r\n         return false;\r\n      }\r\n   });\r\n   if (openRow) {\r\n      console.log('Open row was found');\r\n      allEventDaysCells = $(openRow).children(daysInRange);\r\n      eventCell = $(openRow).children(`.day${startDay}`);\r\n   } else {\r\n      console.log('No open rows for this event. Creating new row');\r\n      let newRow = createRow(resourceId);\r\n      console.log('new row id', newRow.id);\r\n      allEventDaysCells = $(newRow).children(daysInRange);\r\n      eventCell = $(newRow).children(`.day${startDay}`);\r\n   }\r\n\r\n   let eventId = Math.trunc(Math.random() * 100000);\r\n   let eventTitle;\r\n   if (event.datediff > 1) {\r\n      eventTitle = `${event.eventname} - ${event.estimateddailyhours} hrs/day (${event.estimatedhours} total)`;\r\n   } else {\r\n      eventTitle = `${event.eventname} - ${event.estimateddailyhours} hrs`;\r\n   }\r\n\r\n   let eventDivString = `<div id=\"${eventId + 'wrapper'}\"\r\n                            class=\"day${startDay} day${endDay} ${resourceId} event-wrapper\"\r\n                            resource=\"${resourceId}\"\r\n                            start-day=\"${startDay}\"\r\n                            end-day=\"${endDay}\"\r\n                            start-date=\"${event.startdate}\"\r\n                            visual-start-date=\"${visualStartDate}\"\r\n                            end-date = \"${event.enddate}\"\r\n                            visual-end-date=\"${visualEndDate}\"\r\n                            name=\"${event.eventnameraw}\"\r\n                            draggable=\"true\"\r\n                            ondrop=\"moveEvent(event)\"\r\n                            ondragover=\"allowDrop(event)\"\r\n                            onclick=\"eventClick(event)\"\r\n                            duration=\"${event.estimateddailyhours}\">\r\n                                <div id=${eventId}left\r\n                                    class=\"day${startDay} day${endDay} ${resourceId} left resizer\"\r\n                                    resource=\"${resourceId}\"\r\n                                    eventId=\"${eventId}\"\r\n                                    start-day=\"${startDay}\"\r\n                                    end-day=\"${endDay}\"\r\n                                    start-date=\"${event.startdate}\"\r\n                                    visual-start-date=\"${visualStartDate}\"\r\n                                    end-date = \"${event.enddate}\"\r\n                                    visual-end-date=\"${visualEndDate}\"\r\n                                    name=\"${event.eventnameraw}\"\r\n                                    draggable=\"true\"\r\n                                    ondrop=\"moveEvent(event)\"\r\n                                    ondragover=\"allowDrop(event)\"\r\n                                    onclick=\"eventClick(event)\"\r\n                                    duration=\"${event.estimateddailyhours}\"/>\r\n                                <div id=${eventId}right\r\n                                    class=\"day${startDay} day${endDay} ${resourceId} right resizer\"\r\n                                    resource=\"${resourceId}\"\r\n                                    eventId=\"${eventId}\"\r\n                                    start-day=\"${startDay}\"\r\n                                    end-day=\"${endDay}\"\r\n                                    start-date=\"${event.startdate}\"\r\n                                    visual-start-date=\"${visualStartDate}\"\r\n                                    end-date = \"${event.enddate}\"\r\n                                    visual-end-date=\"${visualEndDate}\"\r\n                                    name=\"${event.eventnameraw}\"\r\n                                    draggable=\"true\"\r\n                                    ondrop=\"moveEvent(event)\"\r\n                                    ondragover=\"allowDrop(event)\"\r\n                                    onclick=\"eventClick(event)\"\r\n                                    duration=\"${event.estimateddailyhours}\"/>\r\n                                <div id=${eventId}\r\n                                    class=\"day${startDay} day${endDay} ${resourceId} event\"\r\n                                    resource=\"${resourceId}\"\r\n                                    eventId=\"${eventId}\"\r\n                                    start-day=\"${startDay}\"\r\n                                    end-day=\"${endDay}\"\r\n                                    start-date=\"${event.startdate}\"\r\n                                    visual-start-date=\"${visualStartDate}\"\r\n                                    end-date = \"${event.enddate}\"\r\n                                    visual-end-date=\"${visualEndDate}\"\r\n                                    name=\"${event.eventnameraw}\"\r\n                                    draggable=\"true\"\r\n                                    ondrop=\"moveEvent(event)\"\r\n                                    ondragover=\"allowDrop(event)\"\r\n                                    onclick=\"eventClick(event)\"\r\n                                    duration=\"${event.estimateddailyhours}\">\r\n                                    ${eventTitle}\r\n                                </div>\r\n                            </div>`;\r\n\r\n   allEventDaysCells.each((index, cell) => {\r\n      // Don't want to remove the first cell. That is where I am dropping the event\r\n      if (index > 0) {\r\n         cell.remove();\r\n      }\r\n   });\r\n   let appendResult = eventCell\r\n      .append(eventDivString)\r\n      .on('dragstart', (event) => {\r\n         dragEvent(event);\r\n      });\r\n   if (appendResult.length == 0) {\r\n      console.log('append result', appendResult);\r\n      console.log('String: ', eventDivString);\r\n   }\r\n\r\n   eventCell.attr('colspan', endDay - startDay + 1);\r\n   // add classes for every day in the range so that it can still be found by all of my searches\r\n   let dayClasses;\r\n   for (i = startDay; i <= endDay; i++) {\r\n      dayClasses += ' day' + i;\r\n   }\r\n   eventCell.addClass(dayClasses);\r\n   eventCell.addClass('busy');\r\n   let eventDiv = $(`#${eventId}`);\r\n   console.log('color:', event.color);\r\n   eventDiv.css({ 'background-color': event.color });\r\n   console.log('event add success. id=', eventDiv.attr('id'), eventDiv);\r\n   console.groupEnd('addEvent');\r\n   calcUsage();\r\n   return eventDiv;\r\n};\r\n\r\nlet dragEvent = (event) => {\r\n   let fromCellId = $(event.target).parent().parent().attr('id');\r\n   let type;\r\n   if (event.target.id.includes('left')) {\r\n      type = 'left';\r\n   } else if (event.target.id.includes('right')) {\r\n      type = 'right';\r\n   } else {\r\n      type = 'move';\r\n   }\r\n   console.log(\r\n      'You are dragging div id=',\r\n      event.target.id,\r\n      'from td id=',\r\n      fromCellId,\r\n      'Type:',\r\n      type\r\n   );\r\n\r\n   let dataObject = JSON.stringify({\r\n      fromCellId: fromCellId,\r\n      eventId: event.target.getAttribute('eventId'),\r\n      targetId: event.target.id,\r\n      type: type,\r\n   });\r\n   event.originalEvent.dataTransfer.setData('text', dataObject);\r\n};\r\n\r\nlet eventClick = (event) => {\r\n   event.preventDefault();\r\n   let woNum = event.target.getAttribute('name');\r\n   console.log('Trying to open wo', openModule('Work Order', woNum));\r\n};\r\n\r\nlet allowDrop = (event) => {\r\n   event.preventDefault();\r\n};\r\n\r\nlet moveEvent = (event) => {\r\n   console.groupCollapsed('moveEvent');\r\n   // PULL THE WO API CALLS OUT OF HERE\r\n   // Move event now needs to Save the order to the database with the updated dates. Then run buildCalendar()\r\n   event.preventDefault();\r\n   event.stopPropagation();\r\n   console.log('event', event);\r\n   const dataTransfer = JSON.parse(event.dataTransfer.getData('text'));\r\n   const eventWrapper = document.getElementById(\r\n      `${dataTransfer.eventId + 'wrapper'}`\r\n   );\r\n\r\n   // check all columns width against the cursor to see which day this was dropped into\r\n   console.groupCollapsed('determine day based on position');\r\n   let newDay;\r\n   let dropPosition = event.pageX;\r\n   console.log('Drop Position', dropPosition);\r\n   $('th').each((index, cell) => {\r\n      left = getOffset(cell).left;\r\n      right = left + cell.offsetWidth;\r\n      console.log('left', left);\r\n      console.log('right', right);\r\n      if (dropPosition >= left && dropPosition <= right) {\r\n         newDay = cell.getAttribute('day');\r\n         return false;\r\n      }\r\n   });\r\n   if (!newDay) {\r\n      console.log('Day the event was dropped into could not be found');\r\n      return false;\r\n   }\r\n   console.groupEnd('determine day based on position');\r\n   let woNum = eventWrapper.getAttribute('name');\r\n   let resourceId = event.target.getAttribute('resource');\r\n   let startDate = eventWrapper.getAttribute('start-date');\r\n   let endDate = eventWrapper.getAttribute('end-date');\r\n   let newStartDate, newEndDate, daysToSubtract;\r\n\r\n   switch (dataTransfer.type) {\r\n      case 'left':\r\n         daysToSubtract = moment(\r\n            eventWrapper.getAttribute('start-date')\r\n         ).diff(currentViewWeek.clone().day(newDay), 'days', true);\r\n         console.log('daysToSubtract', daysToSubtract);\r\n         newStartDate = moment(startDate)\r\n            .subtract(daysToSubtract, 'days')\r\n            .format('YYYY-MM-DD[T]HH:mm:ss');\r\n         newEndDate = moment(endDate).format('YYYY-MM-DD[T]HH:mm:ss');\r\n\r\n         break;\r\n      case 'right':\r\n         daysToSubtract = moment(eventWrapper.getAttribute('end-date')).diff(\r\n            currentViewWeek.clone().day(newDay),\r\n            'days',\r\n            true\r\n         );\r\n         console.log('daysToSubtract', daysToSubtract);\r\n         newStartDate = moment(startDate).format('YYYY-MM-DD[T]HH:mm:ss');\r\n         newEndDate = moment(endDate)\r\n            .subtract(daysToSubtract, 'days')\r\n            .format('YYYY-MM-DD[T]HH:mm:ss');\r\n         break;\r\n      case 'move':\r\n         daysToSubtract = moment(eventWrapper.getAttribute('end-date')).diff(\r\n            currentViewWeek.clone().day(newDay),\r\n            'days',\r\n            true\r\n         );\r\n         console.log('daysToSubtract', daysToSubtract);\r\n         newEndDate = moment(endDate)\r\n            .subtract(daysToSubtract, 'days')\r\n            .format('YYYY-MM-DD[T]HH:mm:ss');\r\n         newStartDate = moment(startDate)\r\n            .subtract(daysToSubtract, 'days')\r\n            .format('YYYY-MM-DD[T]HH:mm:ss');\r\n   }\r\n   console.log('New Day: ' + newDay);\r\n   console.log('Original Start Date: ' + startDate);\r\n   console.log('New Start Date: ' + newStartDate);\r\n   console.log('Original End Date: ' + endDate);\r\n   console.log('New End Date: ' + newEndDate);\r\n   console.log('WO Num: ' + woNum);\r\n   console.log('Resource ID: ' + resourceId);\r\n   let updateResponse = updateWOItem(\r\n      newStartDate,\r\n      newEndDate,\r\n      woNum,\r\n      resourceId\r\n   );\r\n   if ((updateResponse = true)) {\r\n      let table = $('table');\r\n      table.empty();\r\n      buildCalendar(tableId, resources, currentViewWeek);\r\n   } else {\r\n      // add a pop up that will tell hte user something went wrong\r\n   }\r\n   console.groupEnd('moveEvent');\r\n   return;\r\n};\r\n\r\nlet updateWOItem = (eventStart, eventEnd, woNum, resourceId) => {\r\n   if (eventStart == null) {\r\n      return 'No Start Date Found';\r\n   }\r\n   console.log(\r\n      '\\r\\nEvent Start = ' + eventStart + ' Event End = ' + eventEnd\r\n   );\r\n   let WONum = { GetWorkOrderRq: { WorkOrderNumber: woNum } };\r\n   console.log('\\r\\nEvent WO Num = ', WONum);\r\n   let WOAPIObject = JSON.parse(\r\n      runApiRequest('GetWorkOrderRq', JSON.stringify(WONum))\r\n   );\r\n\r\n   if (WOAPIObject.hasOwnProperty('ErrorRs')) {\r\n      console.log('\\r\\nUnable to parse API request. WO Num = ', WONum);\r\n      console.log('API Response: ', WOAPIObject);\r\n      return false;\r\n   } else {\r\n      let WO = WOAPIObject.GetWorkOrderRs.WO;\r\n\r\n      // CHECK TO SEE IF THE EVENT HAS AN END DATE\r\n      if (!moment(eventEnd).isValid()) {\r\n         // CHANGE EACH WO ITEM DATE SCHEDULED\r\n         for (i = 0; i < WO.WOItems; i++) {\r\n            WO.WOItems[i].DateScheduled = eventStart;\r\n         }\r\n         // CHANGE WO DATE SCHEDULED/DATE SCHEDULED TO START\r\n         console.log('Event end was null');\r\n         WO.DateScheduled = eventStart;\r\n         WO.DateScheduledToStart = eventStart;\r\n      } else {\r\n         console.log('Event end was not null');\r\n         for (i = 0; i < WO.WOItems; i++) {\r\n            WO.WOItems[i].DateScheduled = eventStart;\r\n         }\r\n\r\n         WO.DateScheduled = eventEnd;\r\n         WO.DateScheduledToStart = eventStart;\r\n         WO.CalCategoryID = resourceId;\r\n      }\r\n\r\n      // FORMAT REQUEST OBJECT\r\n      let WONewDate = { SaveWorkOrderRq: { WO: WO } };\r\n\r\n      // UPDATE THE WORK ORDER AND WO ITEMS\r\n      let SaveWorkOrderResponse = JSON.parse(\r\n         runApiRequest('SaveWorkOrderRq', JSON.stringify(WONewDate))\r\n      );\r\n\r\n      if (SaveWorkOrderResponse.SaveWorkOrderRs.statusCode == 1000) {\r\n         console.log(\r\n            'Work Order ' +\r\n               woNum +\r\n               ' has been successfully updated to start date and end date ' +\r\n               eventStart\r\n         );\r\n         return true;\r\n      } else {\r\n         console.log('An error occured while saving the WO');\r\n         console.log('SaveWorkOrderRs =', SaveWorkOrderResponse);\r\n         return false;\r\n      }\r\n   }\r\n};\r\n\r\n// let moveEventARCHIVED = (event) => {\r\n//   event.preventDefault();\r\n//   event.stopPropagation();\r\n//   const dataTransfer = JSON.parse(event.dataTransfer.getData(\"text\"));\r\n//   if (dataTransfer.type == \"resize\") {\r\n//     resizeEvent(event);\r\n//     return true;\r\n//   }\r\n\r\n//   console.groupCollapsed(\"moveEvent\");\r\n//   console.log(`You dropped it into id=${event.target.id}`);\r\n//   const toCellId = event.target.id,\r\n//     fromCellId = dataTransfer.fromCellId,\r\n//     eventId = dataTransfer.eventId,\r\n//     toCell = $(`td#${toCellId}`),\r\n//     toResourceId = toCell.attr(\"resource\"),\r\n//     fromCell = $(`td#${fromCellId}`),\r\n//     fromResourceId = fromCell.attr(\"resource\"),\r\n//     eventDiv = $(`div#${eventId}wrapper`);\r\n\r\n//   eventDiv.appendTo(toCell);\r\n//   eventDiv.on(\"dragstart\", (event) => {\r\n//     dragEvent(event);\r\n//   });\r\n//   let toColor;\r\n//   for (resource of resources) {\r\n//     resource.id == toResourceId ? (toColor = resource.color) : null;\r\n//   }\r\n//   console.log(\"resource found\", toColor);\r\n//   eventDiv.css({ \"background-color\": toColor });\r\n//   toCell.addClass(\"busy\");\r\n//   fromCell.removeClass(\"busy\");\r\n//   calcUsage();\r\n\r\n//   //Go to the previous row and see if any of the the cells in that row are busy.\r\n//   //If there are none we are going to delete the row\r\n//   let fromRow = fromCell.parent();\r\n//   // have to loop over all of the rows in the tbody so that I can have the index of the from row\r\n//   let removeRow = false;\r\n//   let firstRowFlag = false;\r\n//   let currentRowCount = $(`tr.${fromResourceId}.day`).length;\r\n\r\n//   if (currentRowCount == 1) {\r\n//     console.log(\r\n//       \"this is the last row for the resource. so it is not removed\"\r\n//     );\r\n//     console.groupEnd(\"moveEvent\");\r\n//     return true;\r\n//   }\r\n//   $(`tbody#${fromResourceId}body`)\r\n//     .children(\".day\")\r\n//     .each((index, element) => {\r\n//       console.log(\"element\", element, \"index\", index);\r\n//       if (firstRowFlag) {\r\n//         $(element).prepend($(`td.${fromResourceId}.resource-name`));\r\n//         removeRow = true;\r\n//       } else if ($(element)[0] == fromRow[0])\r\n//         if (!fromRow.children(\".busy\").length) {\r\n//           // if the from row is the first row, and there are more rows. We need to do stuff to the next row and then remove the from row\r\n//           console.log(\"no children in this row are busy\");\r\n//           if (index == 0) {\r\n//             console.log(\"This was the first row\");\r\n//             firstRowFlag = true;\r\n//           } else {\r\n//             removeRow = true;\r\n//           }\r\n//         } else {\r\n//           console.log(\"children in from row are busy. Not removing it\");\r\n//           $(`td.resource-name.${fromResourceId}`).attr(\r\n//             \"rowspan\",\r\n//             currentRowCount + 1 //adding 1 for capacity row\r\n//           );\r\n//         }\r\n//     });\r\n//   if (removeRow) {\r\n//     console.log(\"from row to be removed\", fromRow);\r\n//     $(`td.resource-name.${fromResourceId}`).attr(\"rowspan\", currentRowCount);\r\n//     fromRow.remove();\r\n//   }\r\n//   console.groupEnd(\"moveEvent\");\r\n//   return true;\r\n// };\r\n\r\n// let moveEventBusy = (event) => {\r\n//   event.preventDefault();\r\n//   event.stopPropagation();\r\n//   const dataTransfer = JSON.parse(event.dataTransfer.getData(\"text\"));\r\n//   if (dataTransfer.type == \"resize\") {\r\n//     resizeEventBusy(event);\r\n//     return true;\r\n//   }\r\n//   console.groupCollapsed(\"moveEventBusy\");\r\n//   console.log(`You dropped it into a busy cell eventId=${event.target.id}`);\r\n//   const toCell = $(`div#${event.target.id}`).parent(),\r\n//     fromCellId = dataTransfer.fromCellId,\r\n//     eventId = dataTransfer.eventId,\r\n//     toResourceId = toCell.attr(\"resource\"),\r\n//     fromCell = $(`td#${fromCellId}`),\r\n//     fromResourceId = fromCell.attr(\"resource\"),\r\n//     eventDiv = $(`div#${eventId}`);\r\n\r\n//   //Create new row after the current row\r\n//   let rowCount = $(`tr.${toResourceId}`).length;\r\n//   let newRow = createRow(toResourceId);\r\n//   let newRowToCell = $(newRow).children(\r\n//     `td.day${toCell.attr(\"day\")}.${toResourceId}`\r\n//   );\r\n//   newRowToCell.append(eventDiv).on(\"dragstart\", (event) => {\r\n//     dragEvent(event);\r\n//   });\r\n//   let toColor;\r\n//   for (resource of resources) {\r\n//     resource.id == toResourceId ? (toColor = resource.color) : null;\r\n//   }\r\n//   console.log(\"resource found\", toColor);\r\n//   eventDiv.css({ \"background-color\": toColor });\r\n//   newRowToCell.addClass(\"busy\");\r\n//   fromCell.removeClass(\"busy\");\r\n//   calcUsage();\r\n\r\n//   //Go to the previous row and see if any of the the cells in that row are busy.\r\n//   //If there are none we are going to delete the row\r\n//   let fromRow = fromCell.parent();\r\n//   let currentRowCount = parseInt($(`tr.${fromResourceId}.day`).length);\r\n//   if (currentRowCount == 1) {\r\n//     console.log(\r\n//       \"this is the last row for the resource. so it is not removed\"\r\n//     );\r\n//     console.groupEnd(\"moveEventBusy\");\r\n//     return true;\r\n//   }\r\n//   // have to loop over all of the rows in the tbody so that I can have the index of the from row\r\n//   let firstRowFlag = false;\r\n//   let removeRow = false;\r\n//   $(`tbody#${fromResourceId}body`)\r\n//     .children(\".day\")\r\n//     .each((index, element) => {\r\n//       if (firstRowFlag) {\r\n//         $(element).prepend($(`td.${fromResourceId}.resource-name`));\r\n//         removeRow = true;\r\n//       } else if ($(element)[0] == fromRow[0]) {\r\n//         if (!fromRow.children(\".busy\").length) {\r\n//           // if the from row is the first row, and there are more rows. We need to do stuff to the next row and then remove the from row\r\n//           console.log(\"no children in this row are busy\");\r\n//           if (index == 0) {\r\n//             console.log(\"This was the first row\");\r\n//             firstRowFlag = true;\r\n//           } else {\r\n//             removeRow = true;\r\n//           }\r\n//         } else {\r\n//           console.log(\"Cell(s) in from row are busy. Not removing it\");\r\n//           $(`td.resource-name.${fromResourceId}`).attr(\r\n//             \"rowspan\",\r\n//             currentRowCount + 1 //adding 1 for capacity row\r\n//           );\r\n//         }\r\n//       }\r\n//     });\r\n\r\n//   if (removeRow) {\r\n//     console.log(\"from row to be removed\", fromRow);\r\n//     $(`td.resource-name.${fromResourceId}`).attr(\"rowspan\", currentRowCount);\r\n//     fromRow.remove();\r\n//   }\r\n//   console.groupEnd(\"moveEventBusy\");\r\n//   return true;\r\n// };\r\n\r\nlet changeCalendarWeek = (previous) => {\r\n   let currentDate = moment($('table').attr('date'));\r\n   console.groupCollapsed('changeCalendarWeek');\r\n   console.log('currentDate', currentDate);\r\n   let table = $('table');\r\n   table.empty();\r\n\r\n   let newDate;\r\n   if (previous) {\r\n      console.log('subtracting week');\r\n      newDate = currentDate.clone().subtract(1, 'weeks');\r\n   } else {\r\n      console.log('adding week');\r\n      newDate = currentDate.clone().add(1, 'weeks');\r\n   }\r\n   console.log('new date:', newDate);\r\n   table.attr('date', newDate.format('YYYY-MM-DD'));\r\n   currentViewWeek = newDate;\r\n   buildCalendar(tableId, resources, currentViewWeek);\r\n   console.groupEnd('changeCalendarWeek');\r\n   return true;\r\n};\r\n\r\nlet showCapSettings = (event) => {\r\n   event.stopPropagation();\r\n   let resourceId = $(event.target).attr('resource');\r\n   console.log(`showing capacity modal for ${resourceId}`);\r\n   console.log('pageX', event.pageX, 'pageY', event.pageY);\r\n   let modal = $(`.modal.${resourceId}`);\r\n   modal.css({ top: event.pageY, left: event.pageX });\r\n   modal.toggle();\r\n};\r\n\r\nlet buildCalendar = (tableId, resources, momentDate) => {\r\n   console.groupCollapsed('buildCalendar');\r\n   let tableHeaderString = `<thead><th class=\"resource-name\">${NameOfResource}</th>`;\r\n\r\n   for (let dayOfWeek = 0; dayOfWeek < daysInWeek; dayOfWeek++) {\r\n      let dayName = momentDate.day(dayOfWeek).format(HeaderDateFormat);\r\n      tableHeaderString += `<th class=\"day${dayOfWeek}\" day=\"${dayOfWeek}\">${dayName}</th>`;\r\n   }\r\n\r\n   tableHeaderString += `</thead>`;\r\n   let table = $(`#${tableId}`);\r\n   table.append(tableHeaderString);\r\n   table.attr('date', momentDate.format('YYYY-MM-DD'));\r\n\r\n   resources.forEach((resource) => {\r\n      createRow(resource.id);\r\n   });\r\n   console.log('schedule creation successful');\r\n\r\n   let events = getEventData(momentDate);\r\n   for (event of events) {\r\n      addEvent(event);\r\n   }\r\n   console.groupEnd('buildCalendar');\r\n   return true;\r\n};\r\n\r\nlet capacityChange = (event) => {\r\n   let day = $(event.target).attr('day');\r\n   let resourceId = $(event.target).attr('resource');\r\n   let value = parseInt(event.target.value);\r\n\r\n   for (resource of resources) {\r\n      if (resource.id == resourceId) {\r\n         resource.limits[day] = value;\r\n         break;\r\n      }\r\n   }\r\n};\r\n\r\nlet saveCapacities = (event) => {\r\n   let resourceId = $(event.target).attr('resource');\r\n   console.log('saving capacities for resource id:', resourceId);\r\n   let currentInfo = loadReportData();\r\n   if (!currentInfo) {\r\n      currentInfo = [{}];\r\n   } else {\r\n      currentInfo = JSON.parse(currentInfo);\r\n   }\r\n   console.log('Current Info', currentInfo);\r\n   let newCapacities = [...currentInfo];\r\n   newCapacities[0].capacities = resources;\r\n   console.log('New Capacity Object', newCapacities);\r\n   let saveResponse = saveReportData(JSON.stringify(newCapacities));\r\n   let table = $('table');\r\n   table.empty();\r\n   buildCalendar(tableId, resources, currentViewWeek);\r\n};\r\n\r\nlet resizeEventARCHIVED = (event) => {\r\n   event.preventDefault();\r\n   event.stopPropagation();\r\n   console.groupCollapsed('resizeEvent');\r\n   console.log('You just dropped one of the resize elements');\r\n   console.groupEnd('resizeEvent');\r\n   return true;\r\n};\r\n\r\nlet resizeEventBusyARCHIVED = (event) => {\r\n   event.preventDefault();\r\n   event.stopPropagation();\r\n   console.groupCollapsed('resizeEventBusy');\r\n   console.log(\r\n      'You just dropped one of the resize elements in a busy space'\r\n   );\r\n   console.groupEnd('resizeEventBusy');\r\n   return true;\r\n};\r\n\r\n$(document).ready(() => {\r\n   console.log('Document Ready');\r\n   $('#prev-button').click((event) => changeCalendarWeek(true));\r\n   $('#next-button').click((event) => changeCalendarWeek(false));\r\n   buildCalendar(tableId, resources, currentViewWeek);\r\n   let body = $(document.body);\r\n   body.click((event) => {\r\n      //check to see if we are interacting with any child of a capacity modal element\r\n      if ($(event.target).parents('.capacity-modal').length) {\r\n         return false;\r\n      } else {\r\n         $('.capacity-modal').hide();\r\n      }\r\n   });\r\n});\r\n", "2023-01-05 17:28:07.037000", "Capacity planning separated out by calendar category", "Category Capacity Planning", "", 20, 1, "category-capacity-planning", 0], [25, "_binary \u0001", "@media print {\r\n    html,body {\r\n        height: 100%;\r\n        width: 100%;\r\n        margin: 0;\r\n        padding: 0;\r\n        overflow: hidden;\r\n    }\r\n    \r\n    #button {\r\n        display: none !important;\r\n    }\r\n    \r\n    @page {\r\n        $PRINT{Print|Letter|Print}\r\n    }\r\n}", "2023-01-05 17:28:07.052000", "Default portrait print settings.", "Print Portrait", "", 30, 1, "fb-print-portrait", 0], [26, "_binary \u0001", "@media print {\r\n    html,body {\r\n        height: 100%;\r\n        width: 100%;\r\n        margin: 0;\r\n        padding: 0;\r\n        overflow: hidden;\r\n    }\r\n    \r\n    #button {\r\n        display: none !important;\r\n    }\r\n    \r\n    @page {\r\n        $PRINT{Print|Letter:landscape|Print}\r\n    }\r\n}", "2023-01-05 17:28:07.052000", "Default landscape print settings.", "Print Landscape", "", 30, 1, "fb-print-landscape", 0], [27, "_binary \u0001", "<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n    {% Template Inventory_Watch_List %}\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>Inventory Watch List</title>\r\n</head>\r\n<body>\r\n    <div class=\"overflowHidden\" style=\"position: relative; height: 100%; width: 100%\">\r\n        <div id=\"headerContainer\" style=\"float: left;\">\r\n            <h1>Inventory Watch List</h1>\r\n        </div>\r\n        <div id=\"bodyContainer\">\r\n            <div id=\"body\">\r\n            <table id=report-table class='display' style='width:100%''></table>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <script>\r\n    {% Script Inventory_Watch_List %}\r\n    {% Script Show_Header %}\r\n    </script>\r\n</body>\r\n</html>", "2023-01-05 17:28:07.052000", "Replicates the functionality of the Monitor Module, but adds the option to display it on your dashboard. Watches must be created in the Monitor Module.", "Inventory Watch List", "", 10, 2, "inventory-watch-list", 1], [28, "_binary \u0001", "<link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.datatables.net/v/bs4-4.1.1/jq-3.3.1/jszip-2.5.0/dt-1.10.20/b-1.6.1/b-colvis-1.6.1/b-html5-1.6.1/b-print-1.6.1/cr-1.5.2/fh-3.1.6/r-2.2.3/sc-2.0.1/datatables.min.css\"/>\r\n \r\n<script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js\"></script>\r\n<script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js\"></script>\r\n<script type=\"text/javascript\" src=\"https://cdn.datatables.net/v/bs4-4.1.1/jq-3.3.1/jszip-2.5.0/dt-1.10.20/b-1.6.1/b-colvis-1.6.1/b-html5-1.6.1/b-print-1.6.1/cr-1.5.2/fh-3.1.6/r-2.2.3/sc-2.0.1/datatables.min.js\"></script>\r\n<style type=\"text/css\"> {% Style Inventory_Watch_List %} </style>", "2023-01-05 17:28:07.052000", "Replicates the functionality of the Monitor Module, but adds the option to display it on your dashboard. Watches must be created in the Monitor Module.", "Inventory Watch List", "", 40, 2, "inventory-watch-list", 0], [29, "_binary \u0001", "{% Style Print_Landscape %}\r\n.dot {\r\n  height: 20px;\r\n  width: 20px;\r\n  border-radius: 50%;\r\n  display: inline-block;\r\n}\r\n.fb10 {\r\n  background-color: #28a745 !important;\r\n  z-index: 99;\r\n}\r\n.fb20 {\r\n  background-color: #ffc107;\r\n  z-index: 99;\r\n}\r\n.fb30 {\r\n  background-color: #dc3545;\r\n  z-index: 99;\r\n}\r\ntr > td.stateText {\r\n  color: rgba(0,0,0,0);\r\n  font-size: 1px;\r\n  text-align: center;\r\n}\r\noptgroup {\r\n   background: #d3d3d3;\r\n}\r\n.selector {\r\n   width: 100%;\r\n   margin-bottom: 5px;\r\n}\r\n.csv-button-margin {\r\n    margin-bottom: 10px;\r\n}\r\nbody {\r\n   height: 100%;\r\n   font-family: \"Helvetica Neue\",Helvetica,Arial,sans-serif;\r\n}\r\n\r\n.dropdown-content {\r\n  display: none;\r\n  position: absolute;\r\n  right: 0;\r\n  background-color: #f1f1f1;\r\n  min-width: 160px;\r\n  box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);\r\n  z-index: 9999;\r\n}\r\n\r\n.show {\r\n  display: block;\r\n}\r\ndiv.love-on-top {\r\n  z-index: 2;\r\n  position: relative;\r\n}\r\n/* The Modal (background) */\r\n.modal {\r\n  display: none; /* Hidden by default */\r\n  position: fixed; /* Stay in place */\r\n  z-index: 1; /* Sit on top */\r\n  padding-top: 100px; /* Location of the box */\r\n  left: 0;\r\n  top: 0;\r\n  width: 100%; /* Full width */\r\n  height: 100%; /* Full height */\r\n  overflow: auto; /* Enable scroll if needed */\r\n  background-color: rgb(0, 0, 0); /* Fallback color */\r\n  background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */\r\n}\r\n\r\n/* Modal Content */\r\n.modal-content {\r\n  background-color: #fefefe;\r\n  margin: auto;\r\n  padding: 20px;\r\n  width: 80%;\r\n}\r\n\r\n/* The Close Button */\r\n.close {\r\n  color: #aaaaaa;\r\n  float: right;\r\n  font-size: 28px;\r\n  font-weight: bold;\r\n}\r\n\r\n.close:hover,\r\n.close:focus {\r\n  color: #000;\r\n  text-decoration: none;\r\n  cursor: pointer;\r\n}\r\ndiv.columnWrapper {\r\n   position: relative;\r\n   float: left;\r\n   margin: 5px;\r\n}\r\ndiv.columnWrapper:hover img {\r\n   opacity: 0.5;\r\n}\r\ndiv.columnWrapper:hover button {\r\n   display: block;\r\n}\r\ndiv.columnWrapper button {\r\n   position: absolute;\r\n   display: none;\r\n}\r\ndiv.columnWrapper button.delete {\r\n   top: 1px;\r\n   left: 83%;\r\n   background: lightgray;\r\n   opacity: 0.5;\r\n   text-align: center;\r\n}\r\ndiv.columnWrapper button.delete:hover {\r\n   background: gray;\r\n}\r\n\r\n.hide-button {\r\n   float: right;\r\n   margin-top: -13px;\r\n   font-size: 11px;\r\n   font-family: helvetica;\r\n   color: gray;\r\n}\r\ninput.columnTitle {\r\n   margin: 3px;\r\n   text-align: center;\r\n   width: 75%;\r\n}\r\ndiv.columnWrapper {\r\n   text-align: center;\r\n   display: inline-block;\r\n}\r\ndiv.columnPreview {\r\n   display: inline-block;\r\n   min-width: 50px;\r\n   overflow: stretch;\r\n}\r\ndiv.inline {\r\n   margin-right: 10px;\r\n   display: inline-block;\r\n   margin-bottom: 15px;\r\n   vertical-align: top;\r\n}\r\nbody {\r\n   margin: 15px;\r\n   padding: 0;\r\n}\r\ndiv.header {\r\n   margin-top: 20px;\r\n}\r\n.overflowHidden {\r\n   overflow: hidden;\r\n}\r\n\r\n#chartContainer {\r\n   position: relative;\r\n   height: 85%;\r\n   width: 100vw;\r\n   padding-top: 20px;\r\n}\r\n\r\n@media (max-height: 450px) {\r\n   #chartContainer {\r\n      height: 75%;\r\n   }\r\n}\r\n\r\n@media (max-height: 300px) {\r\n   #chartContainer {\r\n      height: 70%;\r\n   }\r\n}\r\n\r\n\r\n#title {\r\n   font-size: 24px;}\r\n\r\n#headerContainer {\r\n   text-align: center;\r\n}\r\n\r\n.wrapper {\r\n   position: relative;\r\n}\r\ndiv.button-wrapper {\r\n   text-align: center;\r\n}\r\ndiv.column-preview-body {\r\n   height: 105px;\r\n}\r\n.scrolling {\r\n   overflow: auto;\r\n   white-space: nowrap;\r\n}\r\n\r\n/*\r\n * Table styles\r\n */\r\ntable.dataTable {\r\n  width: 100%;\r\n  margin: 0 auto;\r\n  clear: both;\r\n  border-collapse: separate;\r\n  border-spacing: 0;\r\n  /*\r\n   * Header and footer styles\r\n   */\r\n  /*\r\n   * Body styles\r\n   */ }\r\n  table.dataTable thead th,\r\n  table.dataTable tfoot th {\r\n    font-weight: bold; }\r\n  table.dataTable thead th,\r\n  table.dataTable thead td {\r\n    padding: 10px 18px;\r\n    border-bottom: 1px solid #111111; \r\n    background-color: #eaeaea;\r\n    font-size: 14px;}\r\n    table.dataTable thead th:active,\r\n    table.dataTable thead td:active {\r\n      outline: none; }\r\n  table.dataTable tfoot th,\r\n  table.dataTable tfoot td {\r\n    padding: 10px 18px 6px 18px;\r\n    border-top: 1px solid #111111; }\r\n  table.dataTable thead .sorting,\r\n  table.dataTable thead .sorting_asc,\r\n  table.dataTable thead .sorting_desc,\r\n  table.dataTable thead .sorting_asc_disabled,\r\n  table.dataTable thead .sorting_desc_disabled {\r\n    cursor: pointer;\r\n    *cursor: hand;\r\n    background-repeat: no-repeat;\r\n    background-position: center right; }\r\n  table.dataTable thead .sorting {\r\n    background-image: url(\"../images/sort_both.png\"); }\r\n  table.dataTable thead .sorting_asc {\r\n    background-image: url(\"../images/sort_asc.png\"); }\r\n  table.dataTable thead .sorting_desc {\r\n    background-image: url(\"../images/sort_desc.png\"); }\r\n  table.dataTable thead .sorting_asc_disabled {\r\n    background-image: url(\"../images/sort_asc_disabled.png\"); }\r\n  table.dataTable thead .sorting_desc_disabled {\r\n    background-image: url(\"../images/sort_desc_disabled.png\"); }\r\n  table.dataTable tbody tr {\r\n    background-color: white; \r\n    font-size: 13px;}\r\n    table.dataTable tbody tr.selected {\r\n      background-color: #b0bed9; }\r\n  table.dataTable tbody th,\r\n  table.dataTable tbody td {\r\n    padding: 8px 10px; }\r\n  table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {\r\n    border-top: 1px solid #dddddd; }\r\n  table.dataTable.row-border tbody tr:first-child th,\r\n  table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,\r\n  table.dataTable.display tbody tr:first-child td {\r\n    border-top: none; }\r\n  table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {\r\n    border-top: 1px solid #dddddd;\r\n    border-right: 1px solid #dddddd; }\r\n  table.dataTable.cell-border tbody tr th:first-child,\r\n  table.dataTable.cell-border tbody tr td:first-child {\r\n    border-left: 1px solid #dddddd;}\r\n  table.dataTable.cell-border tbody tr:first-child th,\r\n  table.dataTable.cell-border tbody tr:first-child td {\r\n    border-top: none; }\r\n  table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {\r\n    background-color: #f9f9f9; }\r\n    table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {\r\n      background-color: #abb9d3; }\r\n  table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {\r\n    background-color: whitesmoke; }\r\n    table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {\r\n      background-color: #a9b7d1; }\r\n  table.dataTable.order-column tbody tr > .sorting_1,\r\n  table.dataTable.order-column tbody tr > .sorting_2,\r\n  table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,\r\n  table.dataTable.display tbody tr > .sorting_2,\r\n  table.dataTable.display tbody tr > .sorting_3 {\r\n    background-color: #f9f9f9; }\r\n  table.dataTable.order-column tbody tr.selected > .sorting_1,\r\n  table.dataTable.order-column tbody tr.selected > .sorting_2,\r\n  table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,\r\n  table.dataTable.display tbody tr.selected > .sorting_2,\r\n  table.dataTable.display tbody tr.selected > .sorting_3 {\r\n    background-color: #acbad4; }\r\n  table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {\r\n    background-color: #f1f1f1; }\r\n  table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {\r\n    background-color: #f3f3f3; }\r\n  table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {\r\n    background-color: whitesmoke; }\r\n  table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {\r\n    background-color: #a6b3cd; }\r\n  table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {\r\n    background-color: #a7b5ce; }\r\n  table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {\r\n    background-color: #a9b6d0; }\r\n  table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {\r\n    background-color: #f9f9f9; }\r\n  table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {\r\n    background-color: #fbfbfb; }\r\n  table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {\r\n    background-color: #fdfdfd; }\r\n  table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {\r\n    background-color: #acbad4; }\r\n  table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {\r\n    background-color: #adbbd6; }\r\n  table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {\r\n    background-color: #afbdd8; }\r\n  table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {\r\n    background-color: #eaeaea; }\r\n  table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {\r\n    background-color: #ebebeb; }\r\n  table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {\r\n    background-color: #eeeeee; }\r\n  table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {\r\n    background-color: #a1aec7; }\r\n  table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {\r\n    background-color: #a2afc8; }\r\n  table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {\r\n    background-color: #a4b2cb; }\r\n  table.dataTable.no-footer {\r\n    border-bottom: 1px solid #111111; }\r\n  table.dataTable.nowrap th, table.dataTable.nowrap td {\r\n    white-space: nowrap; }\r\n  table.dataTable.compact thead th,\r\n  table.dataTable.compact thead td {\r\n    padding: 4px 17px 4px 4px; }\r\n  table.dataTable.compact tfoot th,\r\n  table.dataTable.compact tfoot td {\r\n    padding: 4px; }\r\n  table.dataTable.compact tbody th,\r\n  table.dataTable.compact tbody td {\r\n    padding: 4px; }\r\n  table.dataTable th.dt-left,\r\n  table.dataTable td.dt-left {\r\n    text-align: left; }\r\n  table.dataTable th.dt-center,\r\n  table.dataTable td.dt-center,\r\n  table.dataTable td.dataTables_empty {\r\n    text-align: center; }\r\n  table.dataTable th.dt-right,\r\n  table.dataTable td.dt-right {\r\n    text-align: right; }\r\n  table.dataTable th.dt-justify,\r\n  table.dataTable td.dt-justify {\r\n    text-align: justify; }\r\n  table.dataTable th.dt-nowrap,\r\n  table.dataTable td.dt-nowrap {\r\n    white-space: nowrap; }\r\n  table.dataTable thead th.dt-head-left,\r\n  table.dataTable thead td.dt-head-left,\r\n  table.dataTable tfoot th.dt-head-left,\r\n  table.dataTable tfoot td.dt-head-left {\r\n    text-align: left; }\r\n  table.dataTable thead th.dt-head-center,\r\n  table.dataTable thead td.dt-head-center,\r\n  table.dataTable tfoot th.dt-head-center,\r\n  table.dataTable tfoot td.dt-head-center {\r\n    text-align: center; }\r\n  table.dataTable thead th.dt-head-right,\r\n  table.dataTable thead td.dt-head-right,\r\n  table.dataTable tfoot th.dt-head-right,\r\n  table.dataTable tfoot td.dt-head-right {\r\n    text-align: right; }\r\n  table.dataTable thead th.dt-head-justify,\r\n  table.dataTable thead td.dt-head-justify,\r\n  table.dataTable tfoot th.dt-head-justify,\r\n  table.dataTable tfoot td.dt-head-justify {\r\n    text-align: justify; }\r\n  table.dataTable thead th.dt-head-nowrap,\r\n  table.dataTable thead td.dt-head-nowrap,\r\n  table.dataTable tfoot th.dt-head-nowrap,\r\n  table.dataTable tfoot td.dt-head-nowrap {\r\n    white-space: nowrap; }\r\n  table.dataTable tbody th.dt-body-left,\r\n  table.dataTable tbody td.dt-body-left {\r\n    text-align: left; }\r\n  table.dataTable tbody th.dt-body-center,\r\n  table.dataTable tbody td.dt-body-center {\r\n    text-align: center; }\r\n  table.dataTable tbody th.dt-body-right,\r\n  table.dataTable tbody td.dt-body-right {\r\n    text-align: right; }\r\n  table.dataTable tbody th.dt-body-justify,\r\n  table.dataTable tbody td.dt-body-justify {\r\n    text-align: justify; }\r\n  table.dataTable tbody th.dt-body-nowrap,\r\n  table.dataTable tbody td.dt-body-nowrap {\r\n    white-space: nowrap; }\r\n \r\ntable.dataTable,\r\ntable.dataTable th,\r\ntable.dataTable td {\r\n  box-sizing: content-box; }\r\n \r\n/*\r\n * Control feature layout\r\n */\r\n.dataTables_wrapper {\r\n  position: relative;\r\n  clear: both;\r\n  *zoom: 1;\r\n  zoom: 1; }\r\n  .dataTables_wrapper .dataTables_length {\r\n    float: left;}\r\n  .dataTables_wrapper .dataTables_filter {\r\n    float: right;}\r\n    .dataTables_wrapper .dataTables_filter input {\r\n      margin-left: 0.5em; }\r\n  .dataTables_wrapper .dataTables_info {\r\n    clear: both;\r\n    float: left;\r\n    padding-top: 0.755em; }\r\n  .dataTables_wrapper .dataTables_paginate {\r\n    float: right;\r\n    text-align: right;\r\n    padding-top: 0.25em; }\r\n    .dataTables_wrapper .dataTables_paginate .paginate_button {\r\n      box-sizing: border-box;\r\n      display: inline-block;\r\n      min-width: 1.5em;\r\n      margin-left: 2px;\r\n      text-align: center;\r\n      text-decoration: none !important;\r\n      cursor: pointer;\r\n      *cursor: hand;\r\n      color: #333333 !important;\r\n      border: 1px solid transparent;\r\n      border-radius: 2px; }\r\n      .dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {\r\n        color: #333333 !important;\r\n        border: 1px solid #979797;\r\n        background-color: white;\r\n        background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, gainsboro));\r\n        /* Chrome,Safari4+ */\r\n        background: -webkit-linear-gradient(top, white 0%, gainsboro 100%);\r\n        /* Chrome10+,Safari5.1+ */\r\n        background: -moz-linear-gradient(top, white 0%, gainsboro 100%);\r\n        /* FF3.6+ */\r\n        background: -ms-linear-gradient(top, white 0%, gainsboro 100%);\r\n        /* IE10+ */\r\n        background: -o-linear-gradient(top, white 0%, gainsboro 100%);\r\n        /* Opera 11.10+ */\r\n        background: linear-gradient(to bottom, white 0%, gainsboro 100%);\r\n        /* W3C */ }\r\n      .dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {\r\n        cursor: default;\r\n        color: #666 !important;\r\n        border: 1px solid transparent;\r\n        background: transparent;\r\n        box-shadow: none; }\r\n      .dataTables_wrapper .dataTables_paginate .paginate_button:hover {\r\n        color: white !important;\r\n        border: 1px solid #d9d9d9;\r\n        background-color: white;\r\n        background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #d9d9d9));\r\n        /* Chrome,Safari4+ */\r\n        background: -webkit-linear-gradient(top, white 0%, #d9d9d9 100%);\r\n        /* Chrome10+,Safari5.1+ */\r\n        background: -moz-linear-gradient(top, white 0%, #d9d9d9 100%);\r\n        /* FF3.6+ */\r\n        background: -ms-linear-gradient(top, white 0%, #d9d9d9 100%);\r\n        /* IE10+ */\r\n        background: -o-linear-gradient(top, white 0%, #d9d9d9 100%);\r\n        /* Opera 11.10+ */\r\n        background: linear-gradient(to bottom, white 0%, #d9d9d9 100%);\r\n        /* W3C */ }\r\n      .dataTables_wrapper .dataTables_paginate .paginate_button:active {\r\n        outline: none;\r\n        background-color: #f3f3f3;\r\n        background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f3f3f3), color-stop(100%, #d4d4d4));\r\n        /* Chrome,Safari4+ */\r\n        background: -webkit-linear-gradient(top, #f3f3f3 0%, #d4d4d4 100%);\r\n        /* Chrome10+,Safari5.1+ */\r\n        background: -moz-linear-gradient(top, #f3f3f3 0%, #d4d4d4 100%);\r\n        /* FF3.6+ */\r\n        background: -ms-linear-gradient(top, #f3f3f3 0%, #d4d4d4 100%);\r\n        /* IE10+ */\r\n        background: -o-linear-gradient(top, #f3f3f3 0%, #d4d4d4 100%);\r\n        /* Opera 11.10+ */\r\n        background: linear-gradient(to bottom, #f3f3f3 0%, #d4d4d4 100%);\r\n        /* W3C */\r\n        box-shadow: inset 0 0 3px #111; }\r\n    .dataTables_wrapper .dataTables_paginate .ellipsis {\r\n      padding: 0 1em; }\r\n  .dataTables_wrapper .dataTables_processing {\r\n    position: absolute;\r\n    top: 50%;\r\n    left: 50%;\r\n    width: 100%;\r\n    height: 40px;\r\n    margin-left: -50%;\r\n    margin-top: -25px;\r\n    padding-top: 20px;\r\n    text-align: center;\r\n    font-size: 10px;\r\n    background-color: white;\r\n    background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));\r\n    background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\r\n    background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\r\n    background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\r\n    background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\r\n    background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); }\r\n  .dataTables_wrapper .dataTables_length,\r\n  .dataTables_wrapper .dataTables_filter,\r\n  .dataTables_wrapper .dataTables_info,\r\n  .dataTables_wrapper .dataTables_processing,\r\n  .dataTables_wrapper .dataTables_paginate {\r\n    color: #333333; }\r\n  .dataTables_wrapper .dataTables_scroll {\r\n    clear: both; }\r\n    .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {\r\n      *margin-top: -1px;\r\n      -webkit-overflow-scrolling: touch; }\r\n      .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td {\r\n        vertical-align: middle; }\r\n      .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th > div.dataTables_sizing,\r\n      .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td > div.dataTables_sizing, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th > div.dataTables_sizing,\r\n      .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td > div.dataTables_sizing {\r\n        height: 0;\r\n        overflow: hidden;\r\n        margin: 0 !important;\r\n        padding: 0 !important; }\r\n  .dataTables_wrapper.no-footer .dataTables_scrollBody {\r\n    border-bottom: 1px solid #111111; }\r\n  .dataTables_wrapper.no-footer div.dataTables_scrollHead table.dataTable,\r\n  .dataTables_wrapper.no-footer div.dataTables_scrollBody > table {\r\n    border-bottom: none; }\r\n  .dataTables_wrapper:after {\r\n    visibility: hidden;\r\n    display: block;\r\n    content: \"\";\r\n    clear: both;\r\n    height: 0; }\r\n \r\n@media screen and (max-width: 767px) {\r\n  .dataTables_wrapper .dataTables_info,\r\n  .dataTables_wrapper .dataTables_paginate {\r\n    float: none;\r\n    text-align: center; }\r\n  .dataTables_wrapper .dataTables_paginate {\r\n    margin-top: 0.5em; } }\r\n@media screen and (max-width: 640px) {\r\n  .dataTables_wrapper .dataTables_length,\r\n  .dataTables_wrapper .dataTables_filter {\r\n    float: none;\r\n    text-align: center; }\r\n  .dataTables_wrapper .dataTables_filter {\r\n    margin-top: 0.5em; } }", "2023-01-05 17:28:07.068000", "Replicates the functionality of the Monitor Module, but adds the option to display it on your dashboard. Watches must be created in the Monitor Module.", "Inventory Watch List", "", 30, 2, "inventory-watch-list", 0], [30, "_binary \u0001", "let partNum = '$PART{Part|%|General}';\r\npartNum == -1 ? (partNum = '%') : true;\r\nlet locationGroupId = '$LG{Location_Group|%|General}';\r\nlocationGroupId == -1 ? (locationGroupId = '%') : true;\r\nlet user = JSON.parse(getUser());\r\nlet currentUser = user.id;\r\n\r\nlet dataset;\r\n\r\nfunction monitor() {\r\n  function getData() {\r\n    let query = `SELECT\r\n      COALESCE((SELECT (sysvalue) * 1000 FROM sysproperties WHERE syskey = 'Refresh Rate'),300000) as refresh,\r\n      watch.id as watchid,\r\n      part.num as partnum,\r\n      part.description as partdescription,\r\n      COALESCE(locationgroup.name,'Company Wide') as locationgroup,\r\n      coalesce(uom.code,'') as uom,\r\n      @avail:= coalesce(IF(coalesce(qtyonhand.qty,0) - coalesce(qtyallocated.qty,0) - coalesce(qtynotavailable.qty,0) + coalesce(qtydropship.qty,0) < 0,0,coalesce(qtyonhand.qty,0) - coalesce(qtyallocated.qty,0) - coalesce(qtynotavailable.qty,0) + coalesce(qtydropship.qty,0))) as avail,\r\n\r\n      @onhand:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(qtyonhand.qty,0) ELSE coalesce(totals.qtyonhand, 0) END) as onhand,\r\n      @available:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(@avail,0) ELSE coalesce(totals.qtyavailable, 0) END) as available,\r\n      @committed:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(qtycommitted.qty,0) ELSE coalesce((SELECT sum(qty) FROM qtycommitted qtyc WHERE qtyc.partid = part.id GROUP BY partid),0) END) as committed,\r\n      @allocated:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(qtyallocated.qty,0) ELSE coalesce(totals.qtyallocated, 0) END) as allocated,\r\n      @notavailable:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(qtynotavailable.qty,0) ELSE coalesce(totals.qtynotavailable, 0) END) as 'not available',\r\n      @onorder:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(qtyonorder.qty,0) ELSE coalesce(totals.qtyonorder, 0) END) as 'on order',\r\n\r\n     (CASE \r\n          WHEN @onhand > watch.alertlevel THEN 'fb10'\r\n          WHEN @onhand <= watch.alertlevel && @onhand > watch.criticallevel THEN 'fb20'\r\n          WHEN @onhand < watch.alertlevel && @onhand <= watch.criticallevel THEN 'fb30'\r\n      END) as state,\r\n      (CASE \r\n        WHEN @onhand > watch.alertlevel THEN '1-Good'\r\n        WHEN @onhand <= watch.alertlevel && @onhand > watch.criticallevel THEN '2-Alert'\r\n        WHEN @onhand < watch.alertlevel && @onhand <= watch.criticallevel THEN '3-Critical'\r\n    END) as statetext\r\n\r\n    FROM watch\r\n\r\n      INNER JOIN part ON watch.itemid = part.id\r\n      INNER JOIN uom ON part.uomid = uom.id\r\n      LEFT OUTER JOIN locationgroup ON watch.locationgroupid = locationgroup.id\r\n      left outer join qtyonhand on (part.id = qtyonhand.partid and locationgroup.id = qtyonhand.locationgroupid)\r\n      left outer join qtycommitted on (part.id = qtycommitted.partid and locationgroup.id = qtycommitted.locationgroupid)\r\n      left outer join qtyallocated on (part.id = qtyallocated.partid and locationgroup.id = qtyallocated.locationgroupid)\r\n      left outer join qtyonorder on (part.id = qtyonorder.partid and locationgroup.id = qtyonorder.locationgroupid)\r\n      left outer join qtynotavailable on (part.id = qtynotavailable.partid and locationgroup.id = qtynotavailable.locationgroupid)\r\n      left outer join qtydropship on (part.id = qtydropship.partid and locationgroup.id = qtydropship.locationgroupid)\r\n      left outer join (select coalesce(sum(qti.qtyonhand),0) as qtyonhand,\r\n                  coalesce(sum(qti.qtyallocated),0) as qtyallocated,\r\n                  coalesce(sum(qti.qtyonorder),0) as qtyonorder,\r\n                  if(coalesce((sum(qti.qtyonhand) - sum(qti.qtyallocated) - sum(qti.qtynotavailable) + sum(qti.qtydropship)),0) < 0,0,coalesce((sum(qti.qtyonhand) - sum(qti.qtyallocated) - sum(qti.qtynotavailable) + sum(qti.qtydropship)),0)) as qtyavailable,                  coalesce(sum(qti.qtynotavailable),0) as qtynotavailable,\r\n                  coalesce(sum(qti.qtydropship),0) as qtydropship, qti.partid\r\n              from qtyinventorytotals qti\r\n              group by qti.partid) as totals on part.id = totals.partid\r\n              \r\n    WHERE part.id LIKE '${partNum}'\r\n            AND COALESCE(locationgroup.id,'') LIKE '${locationGroupId}'\r\n            AND watch.sysuserid LIKE '${currentUser}'`;\r\n\r\n    console.log(query);\r\n    let dataset = JSON.parse(runQuery(query));\r\n    console.log(dataset);\r\n    return dataset;\r\n  }\r\n\r\n  function drawTable() {\r\n    dataset = getData();\r\n\r\n    let table = $('#report-table');\r\n    table.empty();\r\n\r\n    table.DataTable({\r\n      dom: 'B<\"clear\">lfrtip',\r\n      data: dataset,\r\n      columns: [\r\n        {\r\n          title: 'State',\r\n          data: 'statetext',\r\n          defaultContent: '',\r\n          className: 'stateText',\r\n          createdCell: function(td, cellData, rowData, row, col) {\r\n            let statecircle = document.createElement('div');\r\n            console.log(statecircle);\r\n            statecircle.setAttribute('watchid', rowData.watchid);\r\n            td.append(statecircle);\r\n            statecircle.classList.add(rowData.state);\r\n            statecircle.classList.add('dot');\r\n          }\r\n        },\r\n        { title: 'Part Number', data: 'partnum' },\r\n        { title: 'Part Description', data: 'partdescription' },\r\n        { title: 'Location Group', data: 'locationgroup' },\r\n        { title: 'UOM', data: 'uom' },\r\n        { title: 'On Hand', data: 'onhand' },\r\n        { title: 'Available', data: 'available' },\r\n        { title: 'Committed', data: 'committed', defaultContent: '0' },\r\n        { title: 'Allocated', data: 'allocated' },\r\n        { title: 'Not Available', data: 'not available' },\r\n        { title: 'On Order', data: 'on order' }\r\n      ],\r\n      fixedHeader: true,\r\n      colReorder: false,\r\n      pagingType: 'simple',\r\n      responsive: true,\r\n      deferRender: true,\r\n      buttons: ['csv'],\r\n      language: {\r\n        paginate: {\r\n          previous: 'PREV',\r\n          next: 'NEXT'\r\n        }\r\n      }\r\n    });\r\n  }\r\n\r\n  function refreshTable() {\r\n    console.time('refreshRate');\r\n    let table = $('#report-table').DataTable();\r\n    dataset = getData();\r\n    table.clear();\r\n    table.rows.add(dataset);\r\n    table.draw(false);\r\n    console.timeEnd('refreshRate');\r\n    setTimeout(refreshTable, dataset[0].refresh);\r\n  }\r\n\r\n  drawTable();\r\n  $(\".dt-buttons\").addClass( \"csv-button-margin\" );\r\n  console.log(dataset[0].refresh);\r\n  setTimeout(refreshTable, dataset[0].refresh);\r\n}\r\n\r\n$(document).ready(function() {\r\n  monitor();\r\n});\r\n", "2023-01-05 17:28:07.068000", "Replicates the functionality of the Monitor Module, but adds the option to display it on your dashboard. Watches must be created in the Monitor Module.", "Inventory Watch List", "", 20, 2, "inventory-watch-list", 0], [31, "_binary \u0001", "<head>\r\n   <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n   <script src=\"https://code.jquery.com/jquery-3.6.0.js\" integrity=\"sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=\" crossorigin=\"anonymous\"></script>\r\n   <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css\">\r\n   <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\r\n   <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\r\n   <link href=\"https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700;800&display=swap\" rel=\"stylesheet\">  \r\n   <link href=\"https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap\" rel=\"stylesheet\"> \r\n   <style>\r\n   {% Style Part_QR_Code_Label %}\r\n   </style>\r\n</head>\r\n<body>\r\n   \r\n        <div class=\"wrap\">\r\n           <div class=\"toolbar\">\r\n              <button id=\"bold\"><i class=\"fa fa-bold\"></i></button>\r\n              <button id=\"italic\"><i class=\"fa fa-italic\"></i></button>\r\n              <button id=\"underline\"><i class=\"fa fa-underline\"></i></button>\r\n              <select name=\"fonts\" id=\"fonts\" disabled>\r\n                 <option disabled selected value></option>\r\n                 <option value=\"Arial\">Arial</option>\r\n                 <option value=\"Courier New\">Courier New</option>\r\n                 <option value=\"Georgia\">Georgia</option>\r\n                 <option value=\"Impact\">Impact</option>\r\n                 <option value=\"Open Sans\">Open Sans</option>\r\n                 <option value=\"Roboto\">Roboto</option>\r\n                 <option value=\"Tahoma\">Tahoma</option>\r\n                 <option value=\"Times New Roman\">Times New Roman</option>\r\n                 <option value=\"Verdana\">Verdana</option>       \r\n              </select>\r\n              <select name=\"size\" id=\"size\" disabled>\r\n                 <option disabled selected value></option>\r\n                 <option value=\"8\">8</option>\r\n                 <option value=\"10\">10</option>\r\n                 <option value=\"12\">12</option>\r\n                 <option value=\"14\">14</option>\r\n                 <option value=\"16\">16</option>\r\n                 <option value=\"18\">18</option>\r\n                 <option value=\"20\">20</option>\r\n                 <option value=\"22\">22</option>\r\n                 <option value=\"24\">24</option>\r\n                 <option value=\"26\">26</option>\r\n                 <option value=\"28\">28</option>\r\n                 <option value=\"30\">30</option>\r\n                 <option value=\"32\">32</option>\r\n                 <option value=\"34\">34</option>\r\n                 <option value=\"36\">36</option>\r\n              </select>\r\n              <button id=\"align-left\"><i class=\"fa fa-align-left\"></i></button>\r\n              <button id=\"align-center\"><i class=\"fa fa-align-center\"></i></button>\r\n              <button id=\"align-right\"><i class=\"fa fa-align-right\"></i></button>    \r\n              <button id=\"align-top\">\r\n                <div class=\"align-box\">\r\n                    <div class=\"line-top\"></div>\r\n                    <div class=\"line-bottom\"></div>\r\n                </div>\r\n              </button>\r\n              <button id=\"align-middle\">\r\n                <div class=\"align-box\">\r\n                    <div class=\"line-top\"></div>\r\n                    <div class=\"line-bottom\"></div>\r\n                </div>\r\n              </button>\r\n              <button id=\"align-bottom\">\r\n                <div class=\"align-box\">\r\n                    <div class=\"line-top\"></div>\r\n                    <div class=\"line-bottom\"></div>\r\n                </div>\r\n              </button>  \r\n              <label id=\"labelSizeTitle\" for=\"labelSize\" style=\"color: #a6a6a6;\">Label Size (in)</label>\r\n              <input type=\"text\" id=\"labelW\" name=\"labelSize\" style=\"color: #a6a6a6;\" readonly>\r\n              <label id=\"labelSizeX\" for=\"labelSize\" style=\"color: #a6a6a6;\">x</label>\r\n              <input type=\"text\" id=\"labelH\" name=\"labelSize\" style=\"color: #a6a6a6;\" readonly>    \r\n           </div>    \r\n           <div id=\"toolbarButtons\">\r\n               <button id=\"edit\" class=\"hover\">Edit</button>\r\n               <button id=\"save\">Save</button>             \r\n           </div>    \r\n        </div>\r\n        <div id=\"editMode\">\r\n        Edit Mode\r\n        </div>\r\n        <div id=\"mapZoom\">\r\n            <div class=\"plus\">+</div>\r\n            <div class=\"minus\">-</div>\r\n        </div>\r\n        <div id=\"canvas\">\r\n            <div id=\"printable\" class=\"resize\">\r\n                <img id=\"myCanvas\"\r\n                     class=\"qr-code img-thumbnail img-responsive qr-drag\">\r\n                <div id=\"canvasDesc\" class=\"desc-drag\"></div>\r\n                <div id=\"canvasPart\" class=\"part-drag\"></div>\r\n                <div id=\"customText\" class=\"custom-drag\" contenteditable=\"false\" onkeyup=\"checkIt(this.id);\"></div>\r\n            </div>\r\n        </div>\r\n        <div id=\"partContainer\">\r\n                   \r\n        </div>\r\n        <div id=\"pagination\">\r\n            <button class=\"arrow-first\" role=\"button\"><i class=\"fa fa-step-backward\" aria-hidden=\"true\"></i></button>\r\n            <button class=\"arrow-left\" role=\"button\"><i class=\"fa fa-caret-left\" aria-hidden=\"true\"></i></button>\r\n            <div class=\"counter\"></div>\r\n            <button class=\"arrow-right\" role=\"button\"><i class=\"fa fa-caret-right\" aria-hidden=\"true\"></i></button>\r\n            <button class=\"arrow-last\" role=\"button\"><i class=\"fa fa-step-forward\" aria-hidden=\"true\"></i></button>\r\n        </div>\r\n            \r\n</div>\r\n\r\n</body>\r\n<script type=\"module\">\r\nimport interact from 'https://cdn.interactjs.io/v1.9.20/interactjs/index.js'\r\n{% Script Part_QR_Code_Label %}\r\n</script>", "2023-04-20 16:40:15.578000", "Resizable part labels with QR code", "Part QR Code Label", "", 10, 4, "part-qr-code-label", 1], [32, "_binary \u0001", "let zoom = 100;\r\nlet canvas = document.querySelector(\"#canvas\");\r\nlet printable = document.querySelector(\"#printable\");\r\nconst partContainer = document.querySelector('#partContainer');\r\nlet qr = document.querySelector(\".qr-code\");\r\nlet save = document.querySelector(\"#save\");\r\nlet edit = document.querySelector(\"#edit\");  \r\nlet desc = document.querySelector(\".desc-drag\");\r\nlet part = document.querySelector(\".part-drag\");\r\nlet custText = document.querySelector(\".custom-drag\");\r\nlet select = document.querySelector(\".selected\");\r\nlet partNum = '$PART{Part_Number|%|General}';\r\nlet count = '$NUM{Count|90|General}'\r\npartNum == -1 ? (partNum = '%') : true;\r\nlet showDesc = '$CHECK{Show_Description|1|General}';\r\nlet showPart = '$CHECK{Show_Part_Num|1|General}';\r\nlet showBarcode = '$CHECK{Show_Barcode|1|General}';\r\nlet showCustomText = '$CHECK{Show_Custom_Text|0|General}';\r\nlet startRange = '$NUM{Page_Start_From|1|General}';\r\nlet endRange = '$NUM{Through_To_Page|90|General}';\r\nstartRange -= 1;\r\nvar total;\r\nvar limit;\r\nvar offset;\r\nvar qrWidth;\r\nvar editMode = false;\r\nlet LABEL = {\r\n   width: 2,\r\n   height: 1,\r\n   qrWidth: 84,\r\n   qrTransform: \"translate(9px, 5px)\",\r\n   qrTranslateX: 9,\r\n   qrTranslateY: 5,\r\n   partFontSize: 14,\r\n   partTransform: \"translate(98px, 13px)\",\r\n   partTranslateX: 98,\r\n   partTranslateY: 13,\r\n   partWidth: 84.375,\r\n   partHeight: 17,\r\n   partBold: \"false\",\r\n   partItalic: \"false\",\r\n   partUnderlined: \"false\",\r\n   partAlign: \"center\",\r\n   partVAlign: \"start\",\r\n   partFontFamily: \"Arial\",\r\n   descFontSize: 12,\r\n   descTransform: \"translate(98px, 42px)\",\r\n   descTranslateX: 98,\r\n   descTranslateY: 42,\r\n   descWidth: 84.0469,\r\n   descHeight: 42,\r\n   descBold: \"false\",\r\n   descItalic: \"false\",\r\n   descUnderlined: \"false\",\r\n   descAlign: \"center\",\r\n   descVAlign: \"start\",\r\n   descFontFamily: \"Arial\",\r\n   descFontSize: 12,\r\n   custTransform: \"translate(0px, 0px)\",\r\n   custTranslateX: 0,\r\n   custTranslateY: 0,\r\n   custWidth: 84.0469,\r\n   custHeight: 17,\r\n   custBold: \"false\",\r\n   custItalic: \"false\",\r\n   custUnderlined: \"false\",\r\n   custAlign: \"center\",\r\n   custVAlign: \"start\",\r\n   custFontFamily: \"Arial\",\r\n   custFontSize: 12,\r\n   custText: \"Custom Text\",\r\n};\r\n\r\nfunction getLabelData() {\r\n    if (loadReportData() === '') {\r\n        saveReportData(JSON.stringify(LABEL));\r\n    } \r\n    return JSON.parse(loadReportData());\r\n}\r\n\r\n//let savedLabel = LABEL;\r\nlet savedLabel = getLabelData();\r\n\r\nif(savedLabel.custWidth == null) {\r\n    savedLabel.custTransform = LABEL.custTransform;\r\n    savedLabel.custTranslateX = LABEL.custTranslateX;\r\n    savedLabel.custTranslateY = LABEL.custTranslateY;\r\n    savedLabel.custWidth = LABEL.custWidth;\r\n    savedLabel.custHeight = LABEL.custHeight;\r\n    savedLabel.custBold = LABEL.custBold;\r\n    savedLabel.custItalic = LABEL.custItalic;\r\n    savedLabel.custUnderlined = LABEL.custUnderlined;\r\n    savedLabel.custAlign = LABEL.custAlign;\r\n    savedLabel.custFontFamily = LABEL.custFontFamily;\r\n    savedLabel.custFontSize = LABEL.custFontSize;\r\n    savedLabel.custText = LABEL.custText;\r\n}\r\n\r\nif(savedLabel.partVAlign == null) {\r\n    savedLabel.partVAlign = LABEL.partVAlign;\r\n    savedLabel.descVAlign = LABEL.descVAlign;\r\n    savedLabel.custVAlign = LABEL.custVAlign;\r\n}\r\n\r\nif (partNum == '%') {\r\n    limit = endRange - startRange;\r\n    offset = startRange;\r\n} else {\r\n    limit = count;\r\n    offset = 0;\r\n}\r\n\r\n\r\n\r\nvar leftArrow = document.querySelector( '.arrow-left' );\r\nvar rightArrow = document.querySelector( '.arrow-right' );\r\nvar firstArrow = document.querySelector( '.arrow-first' );\r\nvar lastArrow = document.querySelector( '.arrow-last' );\r\n\r\nlet Items = JSON.parse(runQuery(`\r\n    SELECT part.NUM AS partnum, part.description\r\n    FROM part\r\n    WHERE part.id > 0\r\n    AND part.activeflag = 1\r\n    AND part.id LIKE '${partNum}'\r\n    LIMIT ${limit} OFFSET ${offset}\r\n`));\r\ndesc.innerHTML = Items[0].description;\r\npart.innerHTML = Items[0].partnum;\r\n\r\nfunction generateQR(data) {   \r\n    document.getElementById(\"myCanvas\").setAttribute(\"src\", \"http://bwipjs-api.metafloor.com/?bcid=qrcode&text=\" + data + \"&scale=10\");\r\n}; \r\n\r\n\r\n\r\ngenerateQR(Items[0].partnum);\r\n\r\n    function generateCards(length) {\r\n        let i;\r\n        for (let b = 0; b < length; b++) {\r\n            if (partNum == '%'){i = b}else{i = 0};\r\n            document.getElementById(\"partContainer\").insertAdjacentHTML('beforeend',`<div class='card'>\r\n            <img id='qrBarcode_' class='qr-code qr-drag' style=\"transform: ${savedLabel.qrTransform}; width: ${savedLabel.qrWidth}px; height: ${savedLabel.qrWidth}px\">\r\n            <div id='partDesc_' class='title desc-drag' style=\"text-align: ${savedLabel.descAlign}; font-size: ${savedLabel.descFontSize}px; transform: ${savedLabel.descTransform}; width: ${savedLabel.descWidth}px; height: ${savedLabel.descHeight}px;\"></div>\r\n            <div id='partNum_' class='title part-drag' style=\"text-align: ${savedLabel.partAlign}; font-size: ${savedLabel.partFontSize}px; width: ${savedLabel.partWidth}px; height: ${savedLabel.partHeight}px; transform: ${savedLabel.partTransform};\"></div>\r\n            <div id='customText_' class='title custom-drag' style=\"text-align: ${savedLabel.custAlign}; font-size: ${savedLabel.custFontSize}px; width: ${savedLabel.custWidth}px; height: ${savedLabel.custHeight}px; transform: ${savedLabel.custTransform};\"></div>\r\n            <p style=\"page-break-after: always; margin: 0;\"></p></div>`);\r\n            \r\n            document.getElementById(\"partNum_\").setAttribute('id',\"partNum_\" + b.toString());\r\n            document.getElementById(\"qrBarcode_\").setAttribute('id',\"qrBarcode_\" + b.toString());\r\n            document.getElementById(\"partDesc_\").setAttribute('id',\"partDesc_\" + b.toString());\r\n            document.getElementById(\"customText_\").setAttribute('id',\"customText_\" + b.toString());\r\n            document.getElementById(\"qrBarcode_\" + b.toString()).setAttribute(\"src\", \"http://bwipjs-api.metafloor.com/?bcid=qrcode&text=\" + Items[i].partnum + \"&scale=10\");\r\n            \r\n            /******* \r\n            Adding Text to the partnum and description divs   \r\n            *******/\r\n            \r\n            document.getElementById(\"partNum_\" + b.toString()).innerHTML = Items[i].partnum;\r\n            document.getElementById(\"partDesc_\" + b.toString()).innerHTML = Items[i].description; \r\n            document.getElementById(\"customText_\" + b.toString()).innerHTML = savedLabel.custText; \r\n            \r\n        }\r\n    }\r\n\r\nfunction makeCards() {\r\n    if (partNum == '%') {\r\n            total = Items.length; \r\n            generateCards(total);   \r\n    } else {\r\n            total = count;\r\n            generateCards(total); \r\n    } \r\n}  \r\nmakeCards();          \r\n               \r\n              \r\n\r\n\r\nlet index = 1;\r\n    \r\n    document.querySelector( '.counter' ).innerHTML = ( index ) + ' / ' + total;\r\n    \r\n       \r\n    leftArrow.addEventListener('click', (e) => {\r\n        if (index > 1) {\r\n            index -= 1;\r\n            document.querySelector( '.counter' ).innerHTML = ( index  ) + ' / ' + total;\r\n        }\r\n        desc.innerHTML = Items[index - 1].description;\r\n        part.innerHTML = Items[index - 1].partnum;\r\n        generateQR(Items[index - 1].partnum);\r\n    });\r\n    \r\n    rightArrow.addEventListener('click', (e) => {\r\n        if (index < total) {\r\n            index += 1;\r\n            document.querySelector( '.counter' ).innerHTML = ( index  ) + ' / ' + total;\r\n        }\r\n        desc.innerHTML = Items[index - 1].description;\r\n        part.innerHTML = Items[index - 1].partnum;\r\n        generateQR(Items[index - 1].partnum);\r\n    });\r\n    \r\n    firstArrow.addEventListener('click', (e) => {\r\n         if (index != 1) {\r\n             index = 1;\r\n             document.querySelector( '.counter' ).innerHTML = '1 / ' + total;\r\n         }\r\n         desc.innerHTML = Items[0].description;\r\n         part.innerHTML = Items[0].partnum;\r\n         generateQR(Items[0].partnum);\r\n     });\r\n     lastArrow.addEventListener('click', (e) => {\r\n          if (index != total) {\r\n              index = total;\r\n              document.querySelector( '.counter' ).innerHTML = ( total ) + ' / ' + total;\r\n          }\r\n          desc.innerHTML = Items[total - 1].description;\r\n          part.innerHTML = Items[total - 1].partnum;\r\n          generateQR(Items[total - 1].partnum);\r\n      });\r\n\r\n\r\n\r\n\r\n\r\n\r\nvar cssPagedMedia = (function () {\r\n    var style = document.createElement('style');\r\n    document.head.appendChild(style);\r\n    return function (rule) {\r\n        style.innerHTML = rule;\r\n    };\r\n}());\r\n     \r\ncssPagedMedia.size = function (size) {\r\n    cssPagedMedia('@page {size: auto; margin: 0mm;} @media print {@page {size: ' + size + '}}');\r\n};\r\n     \r\ncssPagedMedia.size(savedLabel.width + \"in \" + savedLabel.height + \"in\");\r\n     \r\n     \r\n\r\nfunction resize(Rect){\r\n    interact(\".selected\").resizable({\r\n        edges: { left: true, right: true, bottom: true, top: true },\r\n        listeners: {\r\n            move(event) {\r\n            var target = event.target;\r\n            var rect = event.rect;\r\n            let drag = zoom / 100;\r\n\r\n            // update the element's style\r\n            if (target.classList.contains('qr-code')) {   \r\n                position.x += event.deltaRect.left / drag\r\n                position.y += event.deltaRect.left / drag                 \r\n                target.style.transform = 'translate(' + position.x + 'px,' + position.y + 'px)'                   \r\n                target.setAttribute('data-x', position.x)\r\n                target.setAttribute('data-y', position.y)                              \r\n                target.style.width = Math.floor(rect.width / drag) + \"px\";\r\n                target.style.height = Math.floor(rect.width / drag) + \"px\";\r\n                qrWidth = Math.floor(rect.width / drag);\r\n                savedLabel.qrWidth = Math.floor(rect.width / drag);            \r\n                let qrcodes = document.querySelectorAll(\".qr-code\");\r\n                qrcodes.forEach(function(elem) {\r\n                    elem.style.transform = 'translate(' + position.x + 'px,' + position.y + 'px)'                   \r\n                    elem.setAttribute('data-x', position.x)\r\n                    elem.setAttribute('data-y', position.y)                              \r\n                    elem.style.width = Math.floor(rect.width / drag) + \"px\";\r\n                    elem.style.height = Math.floor(rect.width / drag) + \"px\";\r\n                });                                                                    \r\n                } else {\r\n                    target.style.width = rect.width / drag + \"px\";\r\n                    target.style.height = rect.height / drag + \"px\";\r\n                    \r\n                    if (target.classList.contains(\"part-drag\")) {\r\n                        partposition.x += event.deltaRect.left / drag\r\n                        partposition.y += event.deltaRect.top / drag                 \r\n                        target.style.transform = 'translate(' + partposition.x + 'px,' + partposition.y + 'px)'                   \r\n                        target.setAttribute('data-x', partposition.x)\r\n                        target.setAttribute('data-y', partposition.y)\r\n                        let parts = document.querySelectorAll(\".part-drag\");\r\n                        parts.forEach(function(elem) {\r\n                            elem.style.transform = 'translate(' + partposition.x + 'px,' + partposition.y + 'px)'                 \r\n                            elem.setAttribute('data-x', partposition.x)\r\n                            elem.setAttribute('data-y', partposition.y)    \r\n                            elem.style.width = Math.floor(rect.width / drag) + \"px\";\r\n                            elem.style.height = Math.floor(rect.height / drag) + \"px\";                         \r\n                        });\r\n                        savedLabel.partWidth = rect.width / drag;\r\n                        savedLabel.partHeight = rect.height / drag;\r\n                    } else if (target.classList.contains(\"desc-drag\")) {\r\n                        descposition.x += event.deltaRect.left / drag\r\n                        descposition.y += event.deltaRect.top / drag                 \r\n                        target.style.transform = 'translate(' + descposition.x + 'px,' + descposition.y + 'px)'                   \r\n                        target.setAttribute('data-x', descposition.x)\r\n                        target.setAttribute('data-y', descposition.y)\r\n                        let descs = document.querySelectorAll(\".desc-drag\");\r\n                        descs.forEach(function(elem) {\r\n                            elem.style.transform = 'translate(' + descposition.x + 'px,' + descposition.y + 'px)'                 \r\n                            elem.setAttribute('data-x', descposition.x)\r\n                            elem.setAttribute('data-y', descposition.y)    \r\n                            elem.style.width = Math.floor(rect.width / drag) + \"px\";\r\n                            elem.style.height = Math.floor(rect.height / drag) + \"px\";                         \r\n                        });\r\n                        savedLabel.descWidth = rect.width / drag;\r\n                        savedLabel.descHeight = rect.height / drag;\r\n                    } else if (target.classList.contains(\"custom-drag\")) {\r\n                        custposition.x += event.deltaRect.left / drag\r\n                        custposition.y += event.deltaRect.top / drag                 \r\n                        target.style.transform = 'translate(' + custposition.x + 'px,' + custposition.y + 'px)'                   \r\n                        target.setAttribute('data-x', custposition.x)\r\n                        target.setAttribute('data-y', custposition.y)\r\n                        let custs = document.querySelectorAll(\".custom-drag\");\r\n                        custs.forEach(function(elem) {\r\n                            elem.style.transform = 'translate(' + custposition.x + 'px,' + custposition.y + 'px)'                 \r\n                            elem.setAttribute('data-x', custposition.x)\r\n                            elem.setAttribute('data-y', custposition.y)    \r\n                            elem.style.width = Math.floor(rect.width / drag) + \"px\";\r\n                            elem.style.height = Math.floor(rect.height / drag) + \"px\";                         \r\n                         });\r\n                         savedLabel.custWidth = rect.width / drag;\r\n                         savedLabel.custHeight = rect.height / drag;\r\n                      }\r\n                }                                       \r\n            }\r\n        },\r\n        modifiers: [     \r\n            // minimum size\r\n            interact.modifiers.restrictSize({\r\n                min: { width: 15, height: 15 }\r\n            }),\r\n            interact.modifiers.restrictEdges({\r\n                outer: {\r\n                    left: Rect.left,    \r\n                    right: Rect.right,\r\n                    top: Rect.top,\r\n                    bottom: Rect.bottom  \r\n                }\r\n            })\r\n        ]\r\n                  \r\n    });\r\n};  \r\n\r\n\r\nwindow.addEventListener(\"resize\", (e) => {\r\n    var divRectNew = printable.getBoundingClientRect();\r\n    resize(divRectNew);\r\n});\r\n\r\n  \r\n  $('#labelH').on('change', function() {\r\n   var size = $(this).val();\r\n   $('#printable').css('height', size + 'in');\r\n   $('.card').css('height', size + 'in');\r\n   savedLabel.height = size;\r\n   cssPagedMedia.size($('#labelW').val() + \"in \" + $('#labelH').val() + \"in\");\r\n   var divRectNew = printable.getBoundingClientRect();\r\n   resize(divRectNew);\r\n});\r\n\r\n$('#labelW').on('change', function() {\r\n   var size = $(this).val();\r\n   $('#printable').css('width', size + 'in');\r\n   $('.card').css('width', size + 'in');\r\n   savedLabel.width = size;\r\n   cssPagedMedia.size($('#labelW').val() + \"in \" + $('#labelH').val() + \"in\");\r\n   var divRectNew = printable.getBoundingClientRect();\r\n   resize(divRectNew);\r\n});\r\n\r\n$('#size').on('change', function() {\r\n   var size = $(this).val();\r\n   $('.selected').css('fontSize', size + 'px');\r\n   if ($('.selected').hasClass('desc-drag')) {\r\n      let descs = document.querySelectorAll(\".desc-drag\");\r\n      savedLabel.descFontSize = size;\r\n      descs.forEach(function(elem) {\r\n          elem.style.fontSize = size;                                        \r\n      });\r\n   } else if ($('.selected').hasClass('part-drag')) {\r\n      let parts = document.querySelectorAll(\".part-drag\");\r\n      savedLabel.partFontSize = size;\r\n      parts.forEach(function(elem) {\r\n          elem.style.fontSize = size;                                       \r\n      });\r\n   } else if ($('.selected').hasClass('custom-drag')) {\r\n            let custs = document.querySelectorAll(\".custom-drag\");\r\n            savedLabel.custFontSize = size;\r\n            custs.forEach(function(elem) {\r\n                elem.style.fontSize = size;                                       \r\n            });\r\n         }\r\n   \r\n});\r\n\r\n$('#bold').on('click', function() {\r\n   let parts = document.querySelectorAll(\".part-drag\");\r\n   let descs = document.querySelectorAll(\".desc-drag\");\r\n   let custs = document.querySelectorAll(\".custom-drag\");\r\n   if ($('.selected').hasClass('bold')) {\r\n      if ($('.selected').hasClass('part-drag')) {\r\n          parts.forEach(function(elem) {\r\n              elem.classList.remove('bold');                                       \r\n          });\r\n      } else if ($('.selected').hasClass('desc-drag')) {\r\n          descs.forEach(function(elem) {\r\n              elem.classList.remove('bold');                                       \r\n          });\r\n      } else if ($('.selected').hasClass('custom-drag')) {\r\n                    custs.forEach(function(elem) {\r\n                        elem.classList.remove('bold');                                       \r\n                    });\r\n                };\r\n   } else {\r\n    if ($('.selected').hasClass('part-drag')) {\r\n        parts.forEach(function(elem) {\r\n            elem.classList.add('bold');                                       \r\n        });\r\n    } else if ($('.selected').hasClass('desc-drag')) {\r\n        descs.forEach(function(elem) {\r\n            elem.classList.add('bold');                                       \r\n        });\r\n    } else if ($('.selected').hasClass('custom-drag')) {\r\n                custs.forEach(function(elem) {\r\n                    elem.classList.add('bold');                                       \r\n                });\r\n            };\r\n   }  \r\n});\r\n\r\n$('#italic').on('click', function() {\r\n   let parts = document.querySelectorAll(\".part-drag\");\r\n   let descs = document.querySelectorAll(\".desc-drag\");\r\n   let custs = document.querySelectorAll(\".custom-drag\");\r\n   if ($('.selected').hasClass('italic')) {\r\n      if ($('.selected').hasClass('part-drag')) {\r\n          parts.forEach(function(elem) {\r\n              elem.classList.remove('italic');                                       \r\n          });\r\n      } else if ($('.selected').hasClass('desc-drag')) {\r\n          descs.forEach(function(elem) {\r\n              elem.classList.remove('italic');                                       \r\n          });\r\n      } else if ($('.selected').hasClass('custom-drag')) {\r\n                    custs.forEach(function(elem) {\r\n                        elem.classList.remove('italic');                                       \r\n                    });\r\n                };\r\n   } else {\r\n    if ($('.selected').hasClass('part-drag')) {\r\n        parts.forEach(function(elem) {\r\n            elem.classList.add('italic');                                       \r\n        });\r\n    } else if ($('.selected').hasClass('desc-drag')) {\r\n        descs.forEach(function(elem) {\r\n            elem.classList.add('italic');                                       \r\n        });\r\n    } else if ($('.selected').hasClass('custom-drag')) {\r\n            custs.forEach(function(elem) {\r\n                elem.classList.add('italic');                                       \r\n            });\r\n        };\r\n   }   \r\n});\r\n\r\n$('#underline').on('click', function() {\r\n   let parts = document.querySelectorAll(\".part-drag\");\r\n   let descs = document.querySelectorAll(\".desc-drag\");\r\n   let custs = document.querySelectorAll(\".custom-drag\");\r\n   if ($('.selected').hasClass('underline')) {\r\n      if ($('.selected').hasClass('part-drag')) {\r\n          parts.forEach(function(elem) {\r\n              elem.classList.remove('underline');                                       \r\n          });\r\n      } else if ($('.selected').hasClass('desc-drag')) {\r\n          descs.forEach(function(elem) {\r\n              elem.classList.remove('underline');                                       \r\n          });\r\n      } else if ($('.selected').hasClass('custom-drag')) {\r\n                    custs.forEach(function(elem) {\r\n                        elem.classList.remove('underline');                                       \r\n                    });\r\n                };\r\n   } else {\r\n    if ($('.selected').hasClass('part-drag')) {\r\n        parts.forEach(function(elem) {\r\n            elem.classList.add('underline');                                       \r\n        });\r\n    } else if ($('.selected').hasClass('desc-drag')) {\r\n        descs.forEach(function(elem) {\r\n            elem.classList.add('underline');                                       \r\n        });\r\n    } else if ($('.selected').hasClass('custom-drag')) {\r\n            custs.forEach(function(elem) {\r\n                elem.classList.add('underline');                                       \r\n            });\r\n        };\r\n       }\r\n});\r\n\r\n$('#align-left').on('click', function() {\r\n   document.execCommand('justifyLeft', false, null);\r\n   if ($('.selected').hasClass('part-drag')) {\r\n       savedLabel.partAlign = \"left\";\r\n       let parts = document.querySelectorAll(\".part-drag\");\r\n       parts.forEach(function(elem) {\r\n           elem.style.justifyContent = \"left\";  \r\n           elem.style.textAlign = \"left\";                                        \r\n       });\r\n      } else if ($('.selected').hasClass('desc-drag')) {\r\n       savedLabel.descAlign = \"left\";\r\n       let descs = document.querySelectorAll(\".desc-drag\");\r\n       descs.forEach(function(elem) {\r\n           elem.style.justifyContent = \"left\"; \r\n           elem.style.textAlign = \"left\";                     \r\n       });\r\n      } else if ($('.selected').hasClass('custom-drag')) {\r\n              savedLabel.custAlign = \"left\";\r\n              let custs = document.querySelectorAll(\".custom-drag\");\r\n              custs.forEach(function(elem) {\r\n                  elem.style.justifyContent = \"left\";    \r\n                  elem.style.textAlign = \"left\";                  \r\n              });\r\n             }\r\n});\r\n\r\n$('#align-center').on('click', function() {\r\n   document.execCommand('justifyCenter', false, null);\r\n   if ($('.selected').hasClass('part-drag')) {\r\n      savedLabel.partAlign = \"center\";\r\n      let parts = document.querySelectorAll(\".part-drag\");\r\n      parts.forEach(function(elem) {\r\n          elem.style.justifyContent = \"center\";   \r\n          elem.style.textAlign = \"center\";                                      \r\n      });\r\n     } else if ($('.selected').hasClass('desc-drag')) {\r\n      savedLabel.descAlign = \"center\";\r\n      let descs = document.querySelectorAll(\".desc-drag\");\r\n      descs.forEach(function(elem) {\r\n          elem.style.justifyContent = \"center\";   \r\n          elem.style.textAlign = \"center\";                   \r\n      });\r\n     } else if ($('.selected').hasClass('custom-drag')) {\r\n            savedLabel.custAlign = \"center\";\r\n            let custs = document.querySelectorAll(\".custom-drag\");\r\n            custs.forEach(function(elem) {\r\n                elem.style.justifyContent = \"center\"; \r\n                elem.style.textAlign = \"center\";                     \r\n            });\r\n           }\r\n});\r\n\r\n$('#align-right').on('click', function() {\r\n   document.execCommand('justifyRight', false, null);\r\n   if ($('.selected').hasClass('part-drag')) {\r\n      savedLabel.partAlign = \"right\";\r\n      let parts = document.querySelectorAll(\".part-drag\");\r\n      parts.forEach(function(elem) {\r\n        elem.style.justifyContent = \"right\"; \r\n        elem.style.textAlign = \"right\";                                       \r\n      });\r\n     } else if ($('.selected').hasClass('desc-drag')) {\r\n      savedLabel.descAlign = \"right\";\r\n      let descs = document.querySelectorAll(\".desc-drag\");\r\n      descs.forEach(function(elem) {\r\n          elem.style.justifyContent = \"right\";    \r\n          elem.style.textAlign = \"right\";                   \r\n      });\r\n     } else if ($('.selected').hasClass('custom-drag')) {\r\n            savedLabel.custAlign = \"right\";\r\n            let custs = document.querySelectorAll(\".custom-drag\");\r\n            custs.forEach(function(elem) {\r\n                elem.style.justifyContent = \"right\";    \r\n                elem.style.textAlign = \"right\";                   \r\n            });\r\n           }\r\n});\r\n\r\n$('#align-top').on('click', function() {\r\n   if ($('.selected').hasClass('part-drag')) {\r\n      savedLabel.partVAlign = \"start\";\r\n      let parts = document.querySelectorAll(\".part-drag\");\r\n      parts.forEach(function(elem) {\r\n        elem.style.alignContent = \"start\";                                        \r\n      });\r\n     } else if ($('.selected').hasClass('desc-drag')) {\r\n      savedLabel.descVAlign = \"start\";\r\n      let descs = document.querySelectorAll(\".desc-drag\");\r\n      descs.forEach(function(elem) {\r\n          elem.style.alignContent = \"start\";                     \r\n      });\r\n     } else if ($('.selected').hasClass('custom-drag')) {\r\n            savedLabel.custVAlign = \"start\";\r\n            let custs = document.querySelectorAll(\".custom-drag\");\r\n            custs.forEach(function(elem) {\r\n                elem.style.alignContent = \"start\";                     \r\n            });\r\n           }\r\n});\r\n\r\n$('#align-middle').on('click', function() {\r\n   if ($('.selected').hasClass('part-drag')) {\r\n      savedLabel.partVAlign = \"center\";\r\n      let parts = document.querySelectorAll(\".part-drag\");\r\n      parts.forEach(function(elem) {\r\n        elem.style.alignContent = \"center\";                                        \r\n      });\r\n     } else if ($('.selected').hasClass('desc-drag')) {\r\n      savedLabel.descVAlign = \"center\";\r\n      let descs = document.querySelectorAll(\".desc-drag\");\r\n      descs.forEach(function(elem) {\r\n          elem.style.alignContent = \"center\";                     \r\n      });\r\n     } else if ($('.selected').hasClass('custom-drag')) {\r\n            savedLabel.custVAlign = \"center\";\r\n            let custs = document.querySelectorAll(\".custom-drag\");\r\n            custs.forEach(function(elem) {\r\n                elem.style.alignContent = \"center\";                     \r\n            });\r\n           }\r\n});\r\n\r\n$('#align-bottom').on('click', function() {\r\n   if ($('.selected').hasClass('part-drag')) {\r\n      savedLabel.partVAlign = \"end\";\r\n      let parts = document.querySelectorAll(\".part-drag\");\r\n      parts.forEach(function(elem) {\r\n        elem.style.alignContent = \"end\";                                        \r\n      });\r\n     } else if ($('.selected').hasClass('desc-drag')) {\r\n      savedLabel.descVAlign = \"end\";\r\n      let descs = document.querySelectorAll(\".desc-drag\");\r\n      descs.forEach(function(elem) {\r\n          elem.style.alignContent = \"end\";                     \r\n      });\r\n     } else if ($('.selected').hasClass('custom-drag')) {\r\n            savedLabel.custVAlign = \"end\";\r\n            let custs = document.querySelectorAll(\".custom-drag\");\r\n            custs.forEach(function(elem) {\r\n                elem.style.alignContent = \"end\";                     \r\n            });\r\n           }\r\n});\r\n\r\n$('#fonts').on('change', function() {\r\n   var font = $(this).val();\r\n   if ($('.selected').hasClass('desc-drag')) {\r\n      let descs = document.querySelectorAll(\".desc-drag\");\r\n      savedLabel.descFontFamily = font;\r\n      descs.forEach(function(elem) {\r\n          elem.style.fontFamily = font;                     \r\n      });\r\n   } else if ($('.selected').hasClass('part-drag')) {\r\n      let parts = document.querySelectorAll(\".part-drag\");\r\n      savedLabel.partFontFamily = font;\r\n      parts.forEach(function(elem) {\r\n          elem.style.fontFamily = font;                                        \r\n      });\r\n   } else if ($('.selected').hasClass('custom-drag')) {\r\n            let custs = document.querySelectorAll(\".custom-drag\");\r\n            savedLabel.custFontFamily = font;\r\n            custs.forEach(function(elem) {\r\n                elem.style.fontFamily = font;                                        \r\n            });\r\n         }\r\n});\r\n  \r\n/******* \r\nzoom in & zoom out\r\n*******/ \r\n  \r\n\r\nlet plus = document.querySelector(\".plus\");\r\nplus.addEventListener(\"click\", (e) => {\r\n    if(zoom < 325) {zoom += 25;};\r\n    printable.style.transform = \"scale(\" + zoom / 100 + \")\";\r\n    var divRect = printable.getBoundingClientRect();\r\n    resize(divRect);  \r\n});\r\n  \r\nlet minus = document.querySelector(\".minus\");\r\nminus.addEventListener(\"click\", (e) => {\r\n    if(zoom > 25) {zoom -= 25;};\r\n    printable.style.transform = \"scale(\" + zoom / 100 + \")\";\r\n    var divRect = printable.getBoundingClientRect();\r\n    resize(divRect);  \r\n});\r\n \r\n/******* \r\nitem selection functionality  \r\n*******/ \r\n\r\nfunction removeSelect() {\r\n    let select = document.querySelector(\".selected\");\r\n    if (select != null) {\r\n        select.style.boxShadow = \"0 0 0px 1px grey\"\r\n        select.classList.remove(\"selected\");\r\n    }\r\n}      \r\n      \r\nfunction canvasEvent() {\r\n    let select = document.querySelector(\".selected\");\r\n    if (select != null) {select.classList.remove(\"selected\");};\r\n};    \r\nfunction qrEvent() {\r\n    removeSelect();\r\n    qr.classList.add('selected');\r\n    qr.style.boxShadow = \"0 0 0px 2px #0984e3\";\r\n};  \r\nfunction partEvent() {\r\n    removeSelect();\r\n    part.classList.add('selected');\r\n    part.style.boxShadow = \"0 0 0px 2px #0984e3\";\r\n    let sizeOptions = document.getElementById('size').getElementsByTagName('option');   \r\n    for(var i = 0; i < sizeOptions.length; i++){\r\n        if (sizeOptions[i].value + \"px\" == part.style.fontSize) {\r\n            sizeOptions[i].selected = 'selected';       \r\n        };\r\n    };\r\n    let fontOptions = document.getElementById('fonts').getElementsByTagName('option');  \r\n    for(var i = 0; i < fontOptions.length; i++){\r\n        if (fontOptions[i].value == part.style.fontFamily) {\r\n            fontOptions[i].selected = 'selected';       \r\n        };\r\n    }; \r\n};  \r\nfunction descEvent() {\r\n    removeSelect();\r\n    desc.classList.add('selected');\r\n    desc.style.boxShadow = \"0 0 0px 2px #0984e3\";\r\n    let sizeOptions = document.getElementById('size').getElementsByTagName('option');  \r\n    for(var i = 0; i < sizeOptions.length; i++){\r\n        if (sizeOptions[i].value + \"px\" == desc.style.fontSize) {\r\n            sizeOptions[i].selected = 'selected';       \r\n        };\r\n    };\r\n           \r\n    let fontOptions = document.getElementById('fonts').getElementsByTagName('option');  \r\n    for(var i = 0; i < fontOptions.length; i++){\r\n        if (fontOptions[i].value == desc.style.fontFamily) {\r\n            fontOptions[i].selected = 'selected';   \r\n                     \r\n        };\r\n    };\r\n};    \r\nfunction custTextEvent() {\r\n    removeSelect();\r\n    custText.classList.add('selected');\r\n    custText.style.boxShadow = \"0 0 0px 2px #0984e3\";\r\n    let sizeOptions = document.getElementById('size').getElementsByTagName('option');   \r\n    for(var i = 0; i < sizeOptions.length; i++){\r\n        if (sizeOptions[i].value + \"px\" == custText.style.fontSize) {\r\n            sizeOptions[i].selected = 'selected';       \r\n        };\r\n    };\r\n    let fontOptions = document.getElementById('fonts').getElementsByTagName('option');  \r\n    for(var i = 0; i < fontOptions.length; i++){\r\n        if (fontOptions[i].value == custText.style.fontFamily) {\r\n            fontOptions[i].selected = 'selected';       \r\n        };\r\n    }; \r\n}; \r\nfunction activateEditMode() {      \r\n    if (editMode == false) {      \r\n        canvas.addEventListener(\"click\", removeSelect, true);\r\n     \r\n        if (select != null) {select.classList.remove(\"selected\");}; \r\n        qr.addEventListener(\"click\", qrEvent);\r\n        desc.addEventListener(\"click\", descEvent);   \r\n        part.addEventListener(\"click\", partEvent);\r\n        custText.addEventListener(\"click\", custTextEvent);    \r\n    } else {\r\n        canvas.removeEventListener(\"click\", removeSelect, true);\r\n        qr.removeEventListener(\"click\", qrEvent);\r\n        desc.removeEventListener(\"click\", descEvent);   \r\n        part.removeEventListener(\"click\", partEvent);\r\n        custText.removeEventListener(\"click\", custTextEvent);\r\n    };\r\n };\r\n\r\n  /******* \r\n  dragging items functionality  \r\n  *******/ \r\n  \r\n  \r\nconst position = { x: savedLabel.qrTranslateX, y: savedLabel.qrTranslateY };\r\nconst descposition = { x: savedLabel.descTranslateX, y: savedLabel.descTranslateY };\r\nconst partposition = { x: savedLabel.partTranslateX, y: savedLabel.partTranslateY };\r\nconst custposition = { x: savedLabel.custTranslateX, y: savedLabel.custTranslateY };\r\n  \r\n                       \r\n\r\n  \r\nfunction changeToolbarColors(on) {\r\n    let alignRight = document.querySelector(\"#align-right\");\r\n    let alignLeft = document.querySelector(\"#align-left\");\r\n    let alignCenter = document.querySelector(\"#align-center\");\r\n    let alignBox = document.querySelectorAll(\".align-box\");\r\n    let lineTop = document.querySelectorAll(\".line-top\");\r\n    let lineBottom = document.querySelectorAll(\".line-bottom\");\r\n    let bold = document.querySelector(\"#bold\");\r\n    let italic = document.querySelector(\"#italic\");\r\n    let underline = document.querySelector(\"#underline\");\r\n    let labelSizeTitle = document.querySelector(\"#labelSizeTitle\");\r\n    let labelSizeX = document.querySelector(\"#labelSizeX\");\r\n    let labelW = document.querySelector(\"#labelW\");\r\n    let labelH = document.querySelector(\"#labelH\");\r\n    let toolbarButtons = document.querySelectorAll(\".toolbar button\");\r\n    let save = document.querySelector(\"#save\");\r\n    let edit = document.querySelector(\"#edit\");\r\n    let size = document.querySelector(\"#size\");\r\n    let fonts = document.querySelector(\"#fonts\");\r\n    if (on == true) {\r\n        alignRight.style.color = \"black\";\r\n        alignLeft.style.color = \"black\";\r\n        alignCenter.style.color = \"black\";\r\n        alignBox.forEach(function(elem) {\r\n            elem.style.borderColor = \"black\";\r\n        });\r\n        lineTop.forEach(function(elem) {\r\n            elem.style.background = \"black\";\r\n        });\r\n        lineBottom.forEach(function(elem) {\r\n            elem.style.background = \"black\";\r\n        });\r\n        bold.style.color = \"black\";\r\n        italic.style.color = \"black\";\r\n        underline.style.color = \"black\";\r\n        labelSizeTitle.style.color = \"black\";\r\n        labelSizeX.style.color = \"black\";\r\n        labelW.style.color = \"black\";\r\n        labelH.style.color = \"black\";\r\n        labelW.style.cursor = \"pointer\";\r\n        labelH.style.cursor = \"pointer\";\r\n        size.style.cursor = \"pointer\";\r\n        fonts.style.cursor = \"pointer\";\r\n        toolbarButtons.forEach(function(elem) {\r\n            elem.classList.add('hover');\r\n        });\r\n        save.classList.add('hover');\r\n        save.style.background = \"#153dff\";\r\n        edit.classList.remove('hover');\r\n        edit.style.background = \"#a6a6a6\";\r\n    } else {\r\n        alignRight.style.color = \"#a6a6a6\";\r\n        alignLeft.style.color = \"#a6a6a6\";\r\n        alignCenter.style.color = \"#a6a6a6\";\r\n        alignBox.forEach(function(elem) {\r\n            elem.style.borderColor = \"#a6a6a6\";\r\n        });\r\n        lineTop.forEach(function(elem) {\r\n            elem.style.background = \"#a6a6a6\";\r\n        });\r\n        lineBottom.forEach(function(elem) {\r\n            elem.style.background = \"#a6a6a6\";\r\n        });\r\n        bold.style.color = \"#a6a6a6\";\r\n        italic.style.color = \"#a6a6a6\";\r\n        underline.style.color = \"#a6a6a6\";\r\n        labelSizeTitle.style.color = \"#a6a6a6\";\r\n        labelSizeX.style.color = \"#a6a6a6\";\r\n        labelW.style.color = \"#a6a6a6\";\r\n        labelH.style.color = \"#a6a6a6\";\r\n        labelW.style.cursor = \"default\";\r\n        labelH.style.cursor = \"default\";\r\n        size.style.cursor = \"default\";\r\n        fonts.style.cursor = \"default\";\r\n        toolbarButtons.forEach(function(elem) {\r\n            elem.classList.remove('hover');\r\n        });\r\n        edit.classList.add('hover');\r\n        edit.style.background = \"green\";\r\n        save.classList.remove('hover');\r\n        save.style.background = \"#a6a6a6\";\r\n    }\r\n  \r\n}\r\n  \r\nfunction editButton() {\r\n    let editModeLabel = document.querySelector(\"#editMode\");\r\n    let labelW = document.querySelector(\"#labelW\");\r\n    let labelH = document.querySelector(\"#labelH\");\r\n    let size = document.querySelector(\"#size\");\r\n    let fonts = document.querySelector(\"#fonts\");\r\n    \r\n        \r\n        labelW.removeAttribute('readonly');\r\n        labelH.removeAttribute('readonly');\r\n        size.removeAttribute(\"disabled\");\r\n        size.removeChild(size.options[0]);\r\n        fonts.removeAttribute(\"disabled\");\r\n        fonts.removeChild(fonts.options[0]);\r\n        editModeLabel.style.display = \"block\";\r\n        changeToolbarColors(true);\r\n        interact('.qr-drag').draggable({  \r\n            restrict: {\r\n                restriction: printable,\r\n                elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\r\n            },\r\n            listeners: {\r\n                start (event) {\r\n                    console.log(event.type, event.target)\r\n                },\r\n                move (event) {\r\n                    let drag = zoom / 100;\r\n                    let qrcodes = document.querySelectorAll(\".qr-code\");\r\n                    qrcodes.forEach(function(elem) {\r\n                        elem.style.transform = `translate(${position.x}px, ${position.y}px)`\r\n                    });\r\n                    position.x += event.dx / drag\r\n                    position.y += event.dy / drag\r\n                    event.target.style.transform = `translate(${position.x}px, ${position.y}px)`;\r\n                    savedLabel.qrTransform = `translate(${position.x}px, ${position.y}px)`;\r\n                    savedLabel.qrTranslateX = position.x;\r\n                    savedLabel.qrTranslateY = position.y;\r\n                },\r\n            }\r\n        });\r\n           \r\n        interact('.desc-drag').draggable({ \r\n            restrict: {\r\n                restriction: printable,\r\n                elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\r\n            },\r\n            listeners: {\r\n                start (event) {\r\n                   console.log(event.type, event.target)\r\n                },\r\n                move (event) {\r\n                    let drag = zoom / 100;\r\n                    descposition.x += event.dx / drag\r\n                    descposition.y += event.dy / drag\r\n                    let descriptions = document.querySelectorAll(\".desc-drag\");\r\n                    descriptions.forEach(function(elem) {\r\n                        elem.style.transform = `translate(${descposition.x}px, ${descposition.y}px)`\r\n                    });\r\n                    event.target.style.transform = `translate(${descposition.x}px, ${descposition.y}px)`;\r\n                    savedLabel.descTransform = `translate(${descposition.x}px, ${descposition.y}px)`;\r\n                    savedLabel.descTranslateX = descposition.x;\r\n                    savedLabel.descTranslateY = descposition.y;   \r\n                },\r\n            }\r\n        });\r\n  \r\n        interact('.part-drag').draggable({ \r\n            restrict: {\r\n                restriction: printable,\r\n                elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\r\n            },\r\n            listeners: {\r\n                start (event) {\r\n                    console.log(event.type, event.target)\r\n                },\r\n                move (event) {\r\n                    let drag = zoom / 100;\r\n                    partposition.x += event.dx / drag\r\n                    partposition.y += event.dy / drag\r\n                    let parts = document.querySelectorAll(\".part-drag\");\r\n                    parts.forEach(function(elem) {\r\n                        elem.style.transform = `translate(${partposition.x}px, ${partposition.y}px)`\r\n                    });\r\n                    event.target.style.transform = `translate(${partposition.x}px, ${partposition.y}px)`;\r\n                    savedLabel.partTransform = `translate(${partposition.x}px, ${partposition.y}px)`;\r\n                    savedLabel.partTranslateX = partposition.x;\r\n                    savedLabel.partTranslateY = partposition.y;\r\n                },\r\n            }\r\n        });\r\n        \r\n        interact('.custom-drag').draggable({ \r\n                    restrict: {\r\n                        restriction: printable,\r\n                        elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\r\n                    },\r\n                    listeners: {\r\n                        start (event) {\r\n                            console.log(event.type, event.target)\r\n                        },\r\n                        move (event) {\r\n                            let drag = zoom / 100;\r\n                            custposition.x += event.dx / drag\r\n                            custposition.y += event.dy / drag\r\n                            let custs = document.querySelectorAll(\".custom-drag\");\r\n                            custs.forEach(function(elem) {\r\n                                elem.style.transform = `translate(${custposition.x}px, ${custposition.y}px)`\r\n                            });\r\n                            event.target.style.transform = `translate(${custposition.x}px, ${custposition.y}px)`;\r\n                            savedLabel.custTransform = `translate(${custposition.x}px, ${custposition.y}px)`;\r\n                            savedLabel.custTranslateX = custposition.x;\r\n                            savedLabel.custTranslateY = custposition.y;\r\n                        },\r\n                    }\r\n                });\r\n                \r\n                        document.querySelector(\"#canvasPart\").style.boxShadow = \"0 0 0px 1px grey\";\r\n                        document.querySelector(\"#canvasDesc\").style.boxShadow = \"0 0 0px 1px grey\";\r\n                        document.querySelector(\".qr-code\").style.boxShadow = \"0 0 0px 1px grey\";\r\n                        document.querySelector(\"#customText\").style.boxShadow = \"0 0 0px 1px grey\";\r\n                        custText.contentEditable = \"true\";\r\n                        canvas.addEventListener(\"click\", removeSelect, true);\r\n                             \r\n                        if (select != null) {select.classList.remove(\"selected\");}; \r\n                        qr.addEventListener(\"click\", qrEvent);\r\n                        desc.addEventListener(\"click\", descEvent);   \r\n                        part.addEventListener(\"click\", partEvent);\r\n                        custText.addEventListener(\"click\", custTextEvent); \r\n                        edit.removeEventListener(\"click\", editButton);\r\n                        save.addEventListener(\"click\", saveButton); \r\n    } \r\n    \r\n    function saveButton() {\r\n    let editModeLabel = document.querySelector(\"#editMode\");\r\n        let labelW = document.querySelector(\"#labelW\");\r\n        let labelH = document.querySelector(\"#labelH\");\r\n        let size = document.querySelector(\"#size\");\r\n        let fonts = document.querySelector(\"#fonts\");\r\n        interact('.part-drag').unset();\r\n        interact('.desc-drag').unset();\r\n        interact('.qr-drag').unset();\r\n        interact('.custom-drag').unset();\r\n        editModeLabel.style.display = \"none\";\r\n        changeToolbarColors(false);\r\n        labelW.setAttribute('readonly', 'readonly');\r\n        labelH.setAttribute('readonly', 'readonly');\r\n        size.setAttribute(\"disabled\", \"disabled\");\r\n        size.insertAdjacentHTML('afterbegin',`<option disabled selected value></option>`);\r\n        fonts.setAttribute(\"disabled\", \"disabled\");\r\n        fonts.insertAdjacentHTML('afterbegin',`<option disabled selected value></option>`);\r\n        let select = document.querySelector(\".selected\");\r\n        if (select != null) {\r\n            //select.contentEditable = \"false\"; \r\n            select.style.boxShadow = \"none\"\r\n            select.classList.remove(\"selected\");\r\n        };\r\n    \r\n    \r\n        document.querySelector(\"#canvasPart\").style.boxShadow = \"none\";\r\n        document.querySelector(\"#canvasDesc\").style.boxShadow = \"none\";\r\n        document.querySelector(\".qr-code\").style.boxShadow = \"none\";\r\n        document.querySelector(\"#customText\").style.boxShadow = \"none\";\r\n        custText.contentEditable = \"false\";\r\n        canvas.removeEventListener(\"click\", removeSelect, true);\r\n        qr.removeEventListener(\"click\", qrEvent);\r\n        desc.removeEventListener(\"click\", descEvent);   \r\n        part.removeEventListener(\"click\", partEvent);\r\n        custText.removeEventListener(\"click\", custTextEvent);\r\n          \r\n        savedLabel.custText = custText.innerHTML;\r\n        setToolbarSettings();\r\n        saveReportData(JSON.stringify(savedLabel)); \r\n        getToolbarSettings();\r\n        \r\n        edit.addEventListener(\"click\", editButton);\r\n        save.removeEventListener(\"click\", saveButton);\r\n};\r\n    \r\n/******* \r\nhide/show checkbox functionality  \r\n*******/   \r\n\r\nif (showPart == false) {\r\n    let parts = document.querySelectorAll(\".part-drag\");\r\n    parts.forEach(function(elem) {\r\n        elem.style.display = 'none';\r\n    });\r\n} else {\r\n    let parts = document.querySelectorAll(\".part-drag\");\r\n    parts.forEach(function(elem) {\r\n        elem.style.display = 'flex';\r\n    });\r\n};    \r\n                          \r\nif (showDesc == false) {\r\n    let descriptions = document.querySelectorAll(\".desc-drag\");\r\n    descriptions.forEach(function(elem) {\r\n        elem.style.display = 'none';\r\n    });\r\n} else {\r\n    let descriptions = document.querySelectorAll(\".desc-drag\");\r\n    descriptions.forEach(function(elem) {\r\n        elem.style.display = 'flex';\r\n    });\r\n};\r\n\r\nif (showBarcode == false) {\r\n    let barcodes = document.querySelectorAll(\".qr-code\");\r\n    barcodes.forEach(function(elem) {\r\n        elem.style.display = 'none';\r\n    });\r\n} else {\r\n    let barcodes = document.querySelectorAll(\".qr-code\");\r\n    barcodes.forEach(function(elem) {\r\n        elem.style.display = 'block';\r\n    });\r\n}; \r\n\r\nif (showCustomText == false) {\r\n    let text = document.querySelectorAll(\".custom-drag\");\r\n    text.forEach(function(elem) {\r\n        elem.style.display = 'none';\r\n    });\r\n} else {\r\n    let text = document.querySelectorAll(\".custom-drag\");\r\n    text.forEach(function(elem) {\r\n        elem.style.display = 'flex';\r\n    });\r\n}; \r\n                          \r\n                          \r\nfunction removeAllChildNodes(parent) {\r\n    while (parent.firstChild) {\r\n        parent.removeChild(parent.firstChild);\r\n    }\r\n};\r\n\r\nfunction setToolbarSettings() {\r\n    if (part.classList.contains('bold')) {\r\n        savedLabel.partBold = \"true\";\r\n    } else {\r\n        savedLabel.partBold = \"false\";\r\n    }\r\n    if (part.classList.contains('italic')) {\r\n        savedLabel.partItalic = \"true\";\r\n    } else {\r\n        savedLabel.partItalic = \"false\";\r\n    }\r\n    if (part.classList.contains('underline')) {\r\n        savedLabel.partUnderlined = \"true\";\r\n    } else {\r\n        savedLabel.partUnderlined = \"false\";\r\n    }\r\n    if (desc.classList.contains('bold')) {\r\n        savedLabel.descBold = \"true\";\r\n    } else {\r\n        savedLabel.descBold = \"false\";\r\n    }\r\n    if (desc.classList.contains('italic')) {\r\n        savedLabel.descItalic = \"true\";\r\n    } else {\r\n        savedLabel.descItalic = \"false\";\r\n    }\r\n    if (desc.classList.contains('underline')) {\r\n        savedLabel.descUnderlined = \"true\";\r\n    } else {\r\n        savedLabel.descUnderlined = \"false\";\r\n    }\r\n    if (custText.classList.contains('bold')) {\r\n            savedLabel.custBold = \"true\";\r\n        } else {\r\n            savedLabel.custBold = \"false\";\r\n        }\r\n        if (custText.classList.contains('italic')) {\r\n            savedLabel.custItalic = \"true\";\r\n        } else {\r\n            savedLabel.custItalic = \"false\";\r\n        }\r\n        if (custText.classList.contains('underline')) {\r\n            savedLabel.custUnderlined = \"true\";\r\n        } else {\r\n            savedLabel.custUnderlined = \"false\";\r\n        }\r\n};\r\n\r\n\r\nfunction getToolbarSettings() {\r\n    let parts = document.querySelectorAll(\".part-drag\");\r\n    let descriptions = document.querySelectorAll(\".desc-drag\");\r\n    let customTexts = document.querySelectorAll(\".custom-drag\");\r\n    if (savedLabel.partBold == 'true') { \r\n        parts.forEach(function(elem) {\r\n            elem.classList.add('bold');\r\n        });\r\n    }\r\n    if (savedLabel.partItalic == 'true') {\r\n        parts.forEach(function(elem) {\r\n            elem.classList.add('italic');\r\n        });\r\n    }\r\n    if (savedLabel.partUnderlined == 'true') {\r\n        parts.forEach(function(elem) {\r\n            elem.classList.add('underline');\r\n        });\r\n    }\r\n    if (savedLabel.descBold == 'true') { \r\n        descriptions.forEach(function(elem) {\r\n            elem.classList.add('bold');\r\n        });\r\n    }\r\n    if (savedLabel.descItalic == 'true') {\r\n        descriptions.forEach(function(elem) {\r\n            elem.classList.add('italic');\r\n        });\r\n    }\r\n    if (savedLabel.descUnderlined == 'true') {\r\n        descriptions.forEach(function(elem) {\r\n            elem.classList.add('underline');\r\n        });\r\n    }\r\n    if (savedLabel.custBold == 'true') { \r\n            customTexts.forEach(function(elem) {\r\n                elem.classList.add('bold');\r\n            });\r\n        }\r\n        if (savedLabel.custItalic == 'true') {\r\n            customTexts.forEach(function(elem) {\r\n                elem.classList.add('italic');\r\n            });\r\n        }\r\n        if (savedLabel.custUnderlined == 'true') {\r\n            customTexts.forEach(function(elem) {\r\n                elem.classList.add('underline');\r\n            });\r\n        }\r\n}\r\n\r\n\r\n// save settings //\r\n                                 \r\nlet test;                     \r\n                          \r\n  edit.addEventListener(\"click\", editButton);\r\n \r\n getToolbarSettings();   \r\n qr.style.width = savedLabel.qrWidth + \"px\";\r\n qr.style.height = savedLabel.qrWidth + \"px\";\r\n qr.style.transform = savedLabel.qrTransform;\r\n desc.style.width = savedLabel.descWidth + \"px\";\r\n desc.style.height = savedLabel.descHeight + \"px\";\r\n desc.style.transform = savedLabel.descTransform;\r\n desc.style.fontSize = savedLabel.descFontSize + \"px\";\r\n desc.style.justifyContent = savedLabel.descAlign;\r\n desc.style.textAlign = savedLabel.descAlign;\r\n desc.style.alignContent = savedLabel.descVAlign;\r\n desc.style.fontFamily = savedLabel.descFontFamily;\r\n part.style.width = savedLabel.partWidth + \"px\";\r\n part.style.height = savedLabel.partHeight + \"px\";\r\n part.style.transform = savedLabel.partTransform;\r\n part.style.fontSize = savedLabel.partFontSize + \"px\";\r\n part.style.justifyContent = savedLabel.partAlign;\r\n part.style.textAlign = savedLabel.partAlign;\r\n part.style.alignContent = savedLabel.partVAlign;\r\n part.style.fontFamily = savedLabel.partFontFamily;\r\n custText.style.width = savedLabel.custWidth + \"px\";\r\n  custText.style.height = savedLabel.custHeight + \"px\";\r\n  custText.style.transform = savedLabel.custTransform;\r\n  custText.style.fontSize = savedLabel.custFontSize + \"px\";\r\n  custText.style.justifyContent = savedLabel.custAlign;\r\n  custText.style.textAlgin = savedLabel.custAlign;\r\n  custText.style.alignContent = savedLabel.custVAlign;\r\n  custText.style.fontFamily = savedLabel.custFontFamily;\r\n  custText.innerHTML = savedLabel.custText;\r\n $('.card').css('width', savedLabel.width + 'in');\r\n $('.card').css('height', savedLabel.height + 'in');\r\n $('#printable').css('width', savedLabel.width + 'in');\r\n $('#printable').css('height', savedLabel.height + 'in');  \r\n $('#labelW').val(savedLabel.width);\r\n $('#labelH').val(savedLabel.height);   \r\n var divRect = printable.getBoundingClientRect();\r\n resize(divRect);                              ", "2023-04-20 16:40:15.656000", "Resizable part labels with QR code", "Part QR Code Label", "", 20, 4, "part-qr-code-label", 0], [33, "_binary \u0001", "body {\r\n   font-family: Arial, sans-serif;\r\n   margin: 0;\r\n   padding: 0;\r\n   height: 100vh;\r\n   width: 100vw;\r\n   position: relative;\r\n   background: #ECECEC;\r\n}\r\n\r\n\r\n\r\n\r\n#printable {\r\n    width: 2in;\r\n    height: 1in;\r\n    box-shadow: 0 5px 8px 0 rgba(0,0,0,.4);\r\n    position: absolute;\r\n    left: 0px;\r\n    top: 0px;\r\n    right: 0px;\r\n    bottom: 0px;\r\n    margin: auto;\r\n    z-index: 0;\r\n    background: white;\r\n    transform: scale(1);\r\n    border-radius: 10px;\r\n}\r\n\r\n#canvas {\r\n    position: relative;\r\n    width: 100vw;\r\n    height: 100vh;\r\n    overflow: scroll;\r\n    overflow-x: scroll;\r\n    overflow-y: scroll;\r\n}\r\n\r\n\r\n.wrap {\r\n   display: flex;\r\n   flex-direction: row;\r\n   padding: 10px;\r\n   width: 100% - 20px;\r\n   min-width: 856px;\r\n   background: #fafafa;\r\n   box-shadow: 0 2px 8px 0 rgba(0,0,0,.4);\r\n   z-index: 5;\r\n   justify-content: space-between;\r\n   position: absolute;\r\n   left: 0px;\r\n   top: 0px;\r\n   right: 0px;\r\n   margin: auto;\r\n   z-index: 1;\r\n   cursor: default;\r\n}\r\n\r\n#toolbarButtons {\r\n    display: flex;\r\n    fled-direction: row;\r\n    \r\n}\r\n\r\n\r\n.qr-code {\r\n    position: absolute;\r\n    z-index: 2;\r\n    max-width: 1064px;\r\n    max-height: 1064px;\r\n    min-width: 25px;\r\n    min-height: 25px;\r\n}\r\n\r\n.desc-drag {\r\n    flex-wrap: wrap;\r\n    position: absolute;\r\n    width: fit-content;\r\n    height: fit-content;\r\n    z-index: 2;\r\n    overflow: hidden;  \r\n}\r\n\r\n.part-drag {\r\n    flex-wrap: wrap;\r\n    position: absolute;\r\n    width: fit-content;\r\n    height: fit-content;\r\n    z-index: 2;\r\n    overflow: hidden;\r\n}\r\n\r\n.custom-drag {\r\n    flex-wrap: wrap;\r\n    position: absolute;\r\n    width: fit-content;\r\n    height: fit-content;\r\n    z-index: 2;\r\n    overflow: hidden;\r\n}\r\n\r\n#customText {\r\n    outline: 0px solid transparent;\r\n}\r\n\r\n.selected {\r\n     -webkit-touch-callout: none; \r\n        -webkit-user-select: none; \r\n         -khtml-user-select: none; \r\n           -moz-user-select: none; \r\n            -ms-user-select: none; \r\n                user-select: none;\r\n}\r\n\r\n::selection {\r\n    background-color: transparent;\r\n}\r\n\r\n::moz-selection {\r\n    background-color: transparent;\r\n}\r\n\r\n::webkit-selection {\r\n    background-color: transparent;\r\n}\r\n\r\n.toolbar {\r\n   width: 750px;\r\n   display: flex;\r\n   flex-direction: row;\r\n   justify-content: space-around;\r\n   align-items: center;\r\n}\r\n\r\nbutton {\r\n   width: 30px;\r\n   height: 30px;\r\n   border-radius: 3px;\r\n   background: none;\r\n   border: none;\r\n   box-sizing: border-box;\r\n   padding: 0;\r\n   color: #a6a6a6;\r\n   font-size: 20px;\r\n   outline: none;\r\n}\r\n\r\n.hover:hover {\r\n   border: 1px solid #a6a6a6;\r\n   color: #777;\r\n   cursor: pointer;\r\n}\r\n\r\n\r\n\r\n#bold,\r\n#italic,\r\n#underline {\r\n   font-size: 18px;\r\n}\r\n\r\n#underline,\r\n#align-bottom {\r\n   margin-right: 17px;\r\n}\r\n\r\n#align-left {\r\n   margin-left: 17px;\r\n}\r\n\r\n\r\n\r\n.align-box {\r\n   margin: -2 auto 0;\r\n   height: 18px;\r\n   width: 20px;\r\n   border: 1px solid #a6a6a6;\r\n   border-radius: 2px;\r\n   box-sizing: border-box;\r\n}\r\n\r\n.line-top {\r\n    width: 12px;\r\n    height: 2px;\r\n    background: #a6a6a6;\r\n}\r\n\r\n.line-bottom {\r\n    width: 9px;\r\n    height: 2px;\r\n    background: #a6a6a6;\r\n}\r\n\r\n#align-top .line-top {\r\n    transform: translate(2px, 2.5px);\r\n}   \r\n\r\n#align-top .line-bottom {\r\n    transform: translate(2px, 4.5px);\r\n} \r\n\r\n#align-middle .line-top {\r\n    transform: translate(2px, 5px);\r\n}   \r\n\r\n#align-middle .line-bottom {\r\n    transform: translate(2px, 7px);\r\n} \r\n\r\n#align-bottom .line-top {\r\n    transform: translate(2px, 7.5px);\r\n}   \r\n\r\n#align-bottom .line-bottom {\r\n    transform: translate(2px, 9.5px);\r\n}  \r\n\r\nselect {\r\n   height: 24px;\r\n   font-size: 15px;\r\n   font-weight: bold;\r\n   color: #444;\r\n   background: #fcfcfc;\r\n   border: 1px solid #a6a6a6;\r\n   border-radius: 3px;\r\n   margin: 0;\r\n   outline: none;\r\n}\r\n\r\nselect > option {\r\n   font-size: 15px;\r\n   background: #fafafa;\r\n}\r\n\r\n#fonts {\r\n   width: 140px;\r\n}\r\n\r\n.sp-replacer {\r\n   background: #fcfcfc;\r\n   padding: 1px 2px 1px 3px;\r\n   border-radius: 3px;\r\n   border-color: #a6a6a6;\r\n   margin-top: -1px;\r\n}\r\n\r\n.sp-replacer:hover {\r\n   border-color: #a6a6a6;\r\n   color: inherit;\r\n}\r\n\r\n.sp-preview {\r\n   width: 15px;\r\n   height: 15px;\r\n   border: none;\r\n   margin-top: 2px;\r\n   margin-right: 3px;\r\n}\r\n\r\n.sp-preview-inner, \r\n.sp-alpha-inner, \r\n.sp-thumb-inner {\r\n   border-radius: 3px;\r\n}\r\n\r\n#labelW, #labelH {\r\n    height: 24px;\r\n    width: 35px;\r\n    font-size: 15px;\r\n    font-weight: bold;\r\n    color: #444;\r\n    background: #fcfcfc;\r\n    border: 1px solid #a6a6a6;\r\n    border-radius: 3px;\r\n    margin: 0;\r\n    outline: none;\r\n    text-align: center;\r\n    cursor: default;\r\n}\r\n\r\n#editMode {\r\n    position: absolute;\r\n    top: 68px;\r\n    left: 10px;\r\n    z-index: 1;\r\n    padding: 5px;\r\n    background: #fafafa;\r\n    box-shadow: 0 2px 8px 0 rgba(0,0,0,.4);\r\n    text-align: center; \r\n    display: none;\r\n}\r\n\r\n\r\n#mapZoom {\r\n    width: 16px; \r\n    height: 150px;\r\n    position: absolute;\r\n    top: 68px;\r\n    right: 15px;\r\n    z-index: 1;\r\n}\r\n\r\n\r\n.plus {\r\n    padding: 5px;\r\n    background: #fafafa;\r\n    box-shadow: 0 2px 8px 0 rgba(0,0,0,.4);\r\n    width: 12px;\r\n    height: 12px;\r\n    text-align: center;  \r\n    cursor: pointer;\r\n    line-height: 12px;\r\n    font-weight: medium;\r\n    font-size: 16pt;\r\n}\r\n\r\n\r\n\r\n.minus {\r\n    padding: 5px; \r\n    background: #fafafa;\r\n    box-shadow: 0 2px 8px 0 rgba(0,0,0,.4);\r\n    width: 12px;\r\n    height: 12px;\r\n    text-align: center; \r\n    cursor: pointer; \r\n    line-height: 11px;\r\n    font-weight: medium;\r\n    font-size: 20pt;\r\n}\r\n\r\n\r\n\r\n.fa-plus:before {\r\n    content: \"\\2b\";\r\n}\r\n\r\n.plus:hover, .minus:hover {\r\n    background: #F0F0F0;\r\n}\r\n\r\n\r\n#pagination {\r\n    display: flex;\r\n    flex-direction: row;\r\n    background-color: white;\r\n    display: flex;\r\n    position: absolute;\r\n    bottom: 0;\r\n    left: 0;\r\n    right: 0;\r\n    justify-content: center;\r\n    background: #fafafa;\r\n    box-shadow: -1px 1px 13px rgba(0,0,0,.4);\r\n}\r\n\r\n.arrow-right {\r\n\theight: 10px; \r\n    width: 50px;\r\n    border: 0;\r\n}\r\n\r\n.arrow-right i {\r\n\theight: 100%; \r\n    width: 100%;\r\n    text-align: center;\r\n    font-size: 20pt;\r\n    color: black;\r\n}\r\n\r\n.arrow-right:hover {\r\n    border: 0;\r\n}\r\n\r\n.arrow-left:hover {\r\n    border: 0;\r\n}\r\n\r\n.arrow-left {\r\n\theight: 10px; \r\n\twidth: 50px;\r\n\tborder: 0;\r\n}\r\n\r\n.arrow-left i {\r\n\theight: 100%; \r\n    width: 100%;\r\n    text-align: center;\r\n    font-size: 20pt;\r\n    color: black;\r\n}\r\n\r\n.arrow-first {\r\n    padding-top: 3px;\r\n\theight: 10px; \r\n\twidth: 50px;\r\n\tborder: 0;\r\n}\r\n\r\n.arrow-first i {\r\n\theight: 100%; \r\n    width: 100%;\r\n    text-align: center;\r\n    font-size: 15pt;\r\n    color: black;\r\n}\r\n\r\n.arrow-first:hover {\r\n    border: 0;\r\n}\r\n\r\n.arrow-last {\r\n    padding-top: 3px;\r\n\theight: 10px; \r\n\twidth: 50px;\r\n\tborder: 0;\r\n}\r\n\r\n.arrow-last i {\r\n\theight: 100%; \r\n    width: 100%;\r\n    text-align: center;\r\n    font-size: 15pt;\r\n    color: black;\r\n}\r\n\r\n.arrow-last:hover {\r\n    border: 0;\r\n}\r\n\r\n.counter {\r\n\theight: 30px; \r\n\twidth: 100px;\r\n    text-align: center;\r\n    font-size: 14pt;\r\n    padding-top: 2px;\r\n}\r\n\r\n#partContainer{\r\n  display: none;\r\n}\r\n\r\n.card {\r\n    background: #fff;\r\n    width: 2in;\r\n    height: 1in;\r\n    position: relative;\r\n    overflow: hidden;\r\n}\r\n\r\n\r\n#save {\r\n    background: #a6a6a6;\r\n    width: 80px;\r\n    font-size: 12px;\r\n    color: white;\r\n    margin-left: 15px;\r\n}\r\n\r\n#edit {\r\n    background: green;\r\n    width: 80px;\r\n    font-size: 12px;\r\n    color: white;\r\n    margin-left: 5px;\r\n}\r\n\r\n#editMode {\r\n    background: green;\r\n    color: white;\r\n}\r\n\r\n.bold {\r\n    font-weight: bold;\r\n}\r\n\r\n.italic {\r\n    font-style: italic;\r\n}\r\n\r\n.underline {\r\n    text-decoration: underline;\r\n}\r\n\r\n@media print {\r\n    body {\r\n    margin: 0;\r\n    padding: 0;   \r\n    }\r\n    \r\n    #container {\r\n        display: none;\r\n    }\r\n    \r\n    #printable {\r\n        all: unset;\r\n        display: none;\r\n    }\r\n    \r\n    #partContainer {\r\n        display: block;\r\n    }\r\n    \r\n    \r\n    #pagination {\r\n        display: none;\r\n    }\r\n    \r\n    .wrap {\r\n        display: none;\r\n    }\r\n    \r\n    #editMode {\r\n        display: none !important;\r\n    }\r\n    \r\n    #mapZoom {\r\n        display: none;\r\n    }\r\n    \r\n    #canvas {\r\n        all: unset;\r\n    }\r\n    \r\n    .selected {\r\n        box-shadow: none;\r\n    }\r\n    \r\n    #editMode {\r\n        display: none;\r\n    }\r\n}", "2023-04-20 16:40:15.687000", "Resizable part labels with QR code", "Part QR Code Label", "", 30, 4, "part-qr-code-label", 0]], "truncated": false, "filtered_table_rows_count": 33, "expanded_columns": [], "expandable_columns": [], "columns": ["id", "active", "data", "dateLastModified", "description", "name", "note", "typeId", "fbVersion", "fbName", "published"], "primary_keys": ["id"], "units": {}, "query": {"sql": "select id, active, data, dateLastModified, description, name, note, typeId, fbVersion, fbName, published from biscript order by id limit 51", "params": {}}, "facet_results": {}, "suggested_facets": [{"name": "dateLastModified", "toggle_url": "https://jfrex08-innofiber-archive.hf.space/fishbowl_archive/biscript.json?_facet=dateLastModified"}, {"name": "description", "toggle_url": "https://jfrex08-innofiber-archive.hf.space/fishbowl_archive/biscript.json?_facet=description"}, {"name": "name", "toggle_url": "https://jfrex08-innofiber-archive.hf.space/fishbowl_archive/biscript.json?_facet=name"}, {"name": "note", "toggle_url": "https://jfrex08-innofiber-archive.hf.space/fishbowl_archive/biscript.json?_facet=note"}, {"name": "typeId", "toggle_url": "https://jfrex08-innofiber-archive.hf.space/fishbowl_archive/biscript.json?_facet=typeId"}, {"name": "fbVersion", "toggle_url": "https://jfrex08-innofiber-archive.hf.space/fishbowl_archive/biscript.json?_facet=fbVersion"}, {"name": "fbName", "toggle_url": "https://jfrex08-innofiber-archive.hf.space/fishbowl_archive/biscript.json?_facet=fbName"}, {"name": "published", "toggle_url": "https://jfrex08-innofiber-archive.hf.space/fishbowl_archive/biscript.json?_facet=published"}, {"name": "dateLastModified", "type": "date", "toggle_url": "https://jfrex08-innofiber-archive.hf.space/fishbowl_archive/biscript.json?_facet_date=dateLastModified"}], "next": null, "next_url": null, "private": false, "allow_execute_sql": true, "query_ms": 14.360087050590664}