{"javascript":"$(document).ready(function() {\n\n /////Translate interface\n /////List of localization keys, feel free to extend it.\n InitTranslations({})\n \n $(\".TranslateEn\").on(\"click\", function(event) {\n Translate(\"en\")\n })\n\n $(\".TranslateRu\").on(\"click\", function(event) {\n Translate(\"ru\")\n })\n\n /////Init manual captcha solving interface\n InitManualCaptchaSolver()\n\n /////Show dialogs when clicked on buttons of LinesFromFile or FilesFromDirectory resource types. \n InitFileAndFolderChooserButtons()\n\n /////Hide main global tab header on start\n $(\"#GlobalTabsHeader\").hide()\n\n /////Init dialogs to edit random strings\n InitRandomStringModals()\n\n /////Init validation and resource visibility\n InitResourcesValidationAndVisibility()\n\n /////Init successes and fails graph\n InitPulse()\n\n /////Init browser viewer\n InitBrowserViewer()\n\n /////Api event handler\n Api.SetEventHandler(function(EventType, EventData){\n \n /////Script started, need to switch tabs and update interface\n if(EventType == \"start\")\n {\n UIkit.tab($(\"#GlobalTabsHeader\")[0]).show(1);\n $(\"#CardStatusRunning\").show()\n $(\"#CardStatusStopped\").hide()\n $(\"#ThreadsRunning\").html(\"0\")\n $(\"#Success\").html(\"0\")\n $(\"#Failures\").html(\"0\")\n $(\"#BrowserNumber\").html(\"0\")\n $(\"#BrowserManualNumber\").html(\"0\")\n $(\"#BrowserManualMessage\").hide()\n $(\"#Logs\").css(\"max-height\",\"400px\")\n $(\"#ExpandLog\").show()\n $(\"#HideLog\").hide()\nApi.SetGlobalVariable(\"TEST\",\"test\")\n /////Clear captchas controls\n ClearCaptchas()\n\n /////Refresh result downloaded number\n $(\".ResultNumber\").html(\"0\")\n\n ClearBrowserViewer()\n\n /////Clear successes and fails graph\n ClearPulse();\n /////Clear logs\n $('#Logs').html(\"\")\n }\n\n /////Script stopped, need to update interface\n if(EventType == \"stop\")\n {\n UIkit.tab($(\"#GlobalTabsHeader\")[0]).show(1);\n $(\"#CardStatusRunning\").hide()\n $(\"#CardStatusStopped\").show()\n $(\"#ThreadsRunning\").html(\"0\")\n $(\"#BrowserNumber\").html(\"0\")\n $(\"#BrowserManualNumber\").html(\"0\")\n $(\"#BrowserManualMessage\").hide()\n }\n\n /////Update result number counter\n if(EventType == \"result\")\n {\n let ResultNumberElement = $(\".ResultNumber[data-index=\" + EventData[\"number\"] + \"]\")\n let CurrentValue = parseInt(ResultNumberElement.html())\n ResultNumberElement.html((CurrentValue + 1).toString())\n }\n\n /////Process captcha\n if(EventType == \"captcha\")\n {\n AddCaptcha(EventData[\"id\"],EventData[\"is_image\"],EventData[\"data\"])\n }\n\n /////Script restarted, need to switch tabs\n if(EventType == \"restart\")\n {\n UIkit.tab($(\"#GlobalTabsHeader\")[0]).show(0);\n $(\"#RunScript\").removeAttr(\"disabled\")\n }\n\n\n\n /////Display log\n if(EventType == \"log\")\n {\n let Logs = $('#Logs');\n let LogLine = $(\"
\").addClass(\"log-line\").attr(\"data-log-type\",EventData[\"type\"])\n let Text = $(\"\").text(EventData[\"text\"])\n \n /////Add action id\n if(EventData[\"action_id\"])\n {\n LogLine.append($(\"\").text(\"[\" + EventData[\"action_id\"] + \"] \").addClass(\"uk-text-muted\"))\n }\n\n /////Set color\n if(EventData[\"type\"] == \"success\")\n {\n Text.addClass(\"uk-text-success\")\n }else if (EventData[\"type\"] == \"info\")\n {\n Text.addClass(\"uk-text-muted\")\n }else if (EventData[\"type\"] == \"fail\")\n {\n Text.addClass(\"uk-text-danger\")\n }\n\n /////Remove old lines\n $('#Logs .log-line').slice(500).remove();\n \n\n /////Append text\n LogLine.append(Text)\n Logs.prepend(LogLine)\n }\n\n /////Browser started, need to update running browser label\n if(EventType == \"browser_add\")\n {\n let CurrentValue = parseInt($(\"#BrowserNumber\").html())\n $(\"#BrowserNumber\").html((CurrentValue + 1).toString())\n\n /////Add browser to viewer\n AddBrowser(EventData[\"browser_id\"],EventData[\"thread_number\"])\n }\n /////Browser finished, need to update running browser label\n if(EventType == \"browser_remove\")\n {\n let CurrentValue = parseInt($(\"#BrowserNumber\").html())\n $(\"#BrowserNumber\").html((CurrentValue - 1).toString())\n\n /////Remove browser from viewer\n RemoveBrowser(EventData[\"browser_id\"],EventData[\"thread_number\"])\n }\n\n /////Browser is under user control\n if(EventType == \"manual_control_start\")\n {\n let CurrentValue = parseInt($(\"#BrowserManualNumber\").html()) + 1\n $(\"#BrowserManualNumber\").html((CurrentValue).toString())\n if(CurrentValue > 0)\n $(\"#BrowserManualMessage\").show()\n\n ManualControlStart(EventData[\"browser_id\"])\n }\n /////Browser is under script control\n if(EventType == \"manual_control_end\")\n {\n let CurrentValue = parseInt($(\"#BrowserManualNumber\").html()) - 1\n $(\"#BrowserManualNumber\").html((CurrentValue).toString())\n if(CurrentValue <= 0)\n $(\"#BrowserManualMessage\").hide()\n\n ManualControlStop(EventData[\"browser_id\"])\n }\n\n /////Thread started, need to update running threads label\n if(EventType == \"thread_start\")\n {\n let CurrentValue = parseInt($(\"#ThreadsRunning\").html())\n $(\"#ThreadsRunning\").html((CurrentValue + 1).toString())\n }\n\n /////Thread ended, need to update running threads label and success or failures\n if(EventType == \"thread_end\")\n {\n let CurrentValue = parseInt($(\"#ThreadsRunning\").html())\n $(\"#ThreadsRunning\").html((CurrentValue - 1).toString())\n\n if(EventData[\"success\"])\n {\n CurrentValue = parseInt($(\"#Success\").html())\n $(\"#Success\").html((CurrentValue + 1).toString())\n\n /////Update successes and fails graph\n AddSuccessToPulse()\n }else\n {\n CurrentValue = parseInt($(\"#Failures\").html())\n $(\"#Failures\").html((CurrentValue + 1).toString())\n\n /////Update successes and fails graph\n AddFailsToPulse()\n }\n }\n \n /////Database structure changed, need to update database resources\n if(EventType == \"database_structure_changed\")\n {\n UpdateDatabaseResources()\n }\n\n })\n\n /////Start script after run button is clicked\n $(\"#RunScript\").on(\"click\", function() {\n /////Validate resources\n if(IsResourcesValid())\n {\n /////Disable run button immediately\n $(\"#RunScript\").attr(\"disabled\",\"disabled\")\n /////Start script\n\n Api.AcceptResources()\n }else\n {\n /////Ask user if he want to continue\n UIkit.modal.confirm(tr('There are incorrectly filled fields on the form. Are you sure, that you want to continue?')).then(function() {\n $(\"#RunScript\").attr(\"disabled\",\"disabled\")\n Api.AcceptResources()\n });\n }\n });\n\n /////Show all log\n $(\"#ExpandLog\").on(\"click\", function() {\n $(\"#Logs\").css(\"max-height\",\"100000px\")\n $(\"#ExpandLog\").hide()\n $(\"#HideLog\").show()\n });\n\n /////Hide log partly\n $(\"#HideLog\").on(\"click\", function() {\n $(\"#Logs\").css(\"max-height\",\"400px\")\n $(\"#ExpandLog\").show()\n $(\"#HideLog\").hide()\n });\n \n\n /////Stop script after run button is clicked\n $(\"#StopScript\").on(\"click\", function() {\n /////Ask user if he wants to stop thread instantly\n UIkit.modal.dialog(`
\n
\n
${tr(\"Please select script stop type. If \\\"Wait each thread\\\" option is selected, script won't be stopped until all threads will finish its work and therefore this method will take some time. \\\"Stop instant\\\" will interrupt script at same second, but all thread data will be lost.\")}
\n
\n
\n
\n
\n
\n \n
`);\n \n });\n\n /////Restart script after restart button is clicked\n $(\".RestartScript\").on(\"click\", function() {\n Api.Restart()\n });\n\n /////Show script report\n $(\"#ShowScriptReport\").on(\"click\", function() {\n\n \n ///// Show modal\n let dialog = UIkit.modal(`
\n
\n \n
\n
\n

${tr('Script report')}

\n
\n
Loading ...
\n
\n
\n
`)\n\n dialog.show()\n\n let IsDialogOpen = true\n\n /////Destroy report when hidden \n UIkit.util.on(\"#ReportModal\", 'hidden', function () {\n dialog.$destroy(true);\n IsDialogOpen = false\n });\n \n let ShowScriptReport = function()\n { \n /////Set script report data\n Api.GetScriptReport().then((res) => {\n \n if(!IsDialogOpen)\n return\n\n $(\"#ScriptReportResult\").html(res)\n /////Autoupdate\n setTimeout(ShowScriptReport,3000)\n }) \n }\n\n ShowScriptReport()\n \n });\n\n /////Show resources report\n $(\"#ResourcesReport\").on(\"click\", function() {\n\n ///// Show modal\n let dialog = UIkit.modal(`
\n
\n \n
\n
\n

${tr('Resources report')}

\n
\n
Loading ...
\n
\n
\n
`)\n\n dialog.show()\n\n let IsDialogOpen = true\n\n /////Destroy report when hidden \n UIkit.util.on(\"#ReportModal\", 'hidden', function () {\n dialog.$destroy(true);\n IsDialogOpen = false\n\n });\n \n let ShowResourcesReport = function()\n { \n /////Set script report data\n Api.GetResourcesReport().then((res) => {\n \n if(!IsDialogOpen)\n return\n\n $(\"#ResourcesReportResult\").html(res)\n /////Autoupdate\n setTimeout(ShowResourcesReport,3000)\n }) \n }\n\n ShowResourcesReport()\n \n });\n\n /////Initialize menus\n $(\"#Menu1\").attr(\"uk-offcanvas\",\"overlay: true\")\n $(\"#Menu1Content\").addClass(\"uk-offcanvas-bar\")\n\n $(\"#Menu2\").attr(\"uk-offcanvas\",\"overlay: true\")\n $(\"#Menu2Content\").addClass(\"uk-offcanvas-bar\")\n \n $(\"#Menu1Button\").on(\"click\", function() {\n UIkit.offcanvas(\"#Menu1\").show();\n });\n\n $(\"#Menu2Button\").on(\"click\", function() {\n UIkit.offcanvas(\"#Menu2\").show();\n });\n\n /////Close menu after click on any link\n $(\"#Menu1 a\").click(function(){\n UIkit.offcanvas(\"#Menu1\").hide();\n })\n\n $(\"#Menu2 a\").click(function(){\n UIkit.offcanvas(\"#Menu2\").hide();\n })\n \n /////Show about window\n $(\".About\").on(\"click\", function() {\n UIkit.modal.alert(`\n
${tr('Script name')}:
\n
dialog *
\n
${tr('Version')}:
\n
1.0.0
\n
* ${tr('Made with')} BrowserAutomationStudio.
\n `)\n });\n\n /////Show schedule\n $(\".ShowScheduler\").on(\"click\", function() {\n Api.ShowScheduler();\n });\n\n /////Hide if no scheduler inside this script\n if(typeof(Api.HasScheduler) == \"undefined\" || !Api.HasScheduler())\n {\n $(\".ShowScheduler\").hide()\n }\n\n /////Download log\n $(\"#DownloadLog\").on(\"click\", function() {\n Api.DownloadLog().then((res) => {\n var blob = new Blob([res], {type: \"text/plain;charset=utf-8\"});\n saveAs(blob, \"dialog.log.txt\");\n })\n });\n\n /////Download results\n $(\".DownloadResult\").on(\"click\", function(event) {\n let el = $(event.target.closest(\".DownloadResult\"))\n let index = parseInt(el.attr(\"data-index\"))\n Api.DownloadResult(index).then((res) => {\n var blob = new Blob([res], {type: \"text/plain;charset=utf-8\"});\n saveAs(blob, \"dialog.results.\" + index + \".txt\");\n })\n });\n\n /////Restore default resources values\n $(\"#RestoreDefaults\").on(\"click\", function(event) {\n /////Find all resources with default values\n $(\"[data-default-value]\").each(function(index, el){\n /////SetValue is function, that sets resource value\n SetValue($(el).attr(\"data-resource-name\"), $(el).attr(\"data-default-value\"))\n })\n });\n\n \n \n /////Autoload resources, which was entered last time, may be removed.\n Api.AutoLoadResources()\n\n /////After everything is initialized may show body\n $(\"body\").fadeIn()\n\n /////Events\n\n function handleFileSelect(evt) {\n evt.stopPropagation();\n evt.preventDefault();\n\n var files = evt.dataTransfer.files;\n\n var output = [];\n for (var i = 0, f; f = files[i]; i++) {\n output.push(escape(f.name));\n var reader = new FileReader();\n reader.onload = function (e) {\n res = res + e.target.result + \"\\r\\n\";\n }\n reader.readAsText(f);\n }\n $(\"#drop_file\").text(output.join(', '))\n }\n\n function handleDragOver(evt) {\n $(\"#drop_file\").addClass('highlight')\n evt.stopPropagation();\n evt.preventDefault();\n evt.dataTransfer.dropEffect = 'copy';\n }\n\n var drop_file = document.getElementById('drop_file');\n drop_file.addEventListener('dragover', handleDragOver, false);\n drop_file.addEventListener('drop', handleFileSelect, false);\n\n});\n\n\n\n\n\n/////Resource values are obtained through this function when hitting run button, you can change it.\n/////For example, you can edit value entered by user, make custom validation, or replace resource system compleatelly\nvar res = \"\"\nfunction GetResourceValue(ResourceName){\n if(ResourceName == \"file\"){\n return res\n }\n return GetValue(ResourceName)\n}\n\n\n/////When script is started, or restarted, default resource values are set with SetResourceValue function.\n/////You can override default behaviour by changing this function. \nfunction SetResourceValue(ResourceName, ResourceValue)\n{\n return SetValue(ResourceName, ResourceValue)\n}\n\n","cssFiles":["https://bablosoft.com/buildinterface/uikit/css/uikit.css"],"jsFiles":["https://bablosoft.com/buildinterface/jquery/jquery.min.js?v=2","https://bablosoft.com/buildinterface/uikit/js/uikit.js?v=2","https://bablosoft.com/buildinterface/uikit/js/uikit-icons.js?v=2","https://bablosoft.com/buildinterface/charts/utils.js?v=2","https://bablosoft.com/buildinterface/charts/charts.js?v=2","https://bablosoft.com/buildinterface/filesaver/FileSaver.min.js?v=2","https://bablosoft.com/buildinterface/interface-extensions/extensions.js?v=2","https://bablosoft.com/buildinterface/bas-api/bas-api.js?v=2"],"css":"\n\n .file-item\n {\n width: 150px;\n height: 130px;\n padding: 10px;\n font-size: small;\n overflow: hidden;\n margin-right:20px;\n cursor: pointer;\n\n }\n\n\n #Menu1Content li\n {\n margin-bottom:20px\n }\n #Menu2Content li\n {\n margin-bottom:15px\n }\n pre {\n white-space: pre-wrap;\n white-space: -moz-pre-wrap;\n white-space: -pre-wrap;\n white-space: -o-pre-wrap;\n word-wrap: break-word;\n }\n #Logs\n {\n margin-left:10px;\n font-size:small;\n max-height: 400px;\n overflow: hidden;\n\n }\n .ui-panel\n {\n display: flex;\n flex-direction: column;\n }\n\n .ui-panel-body\n {\n flex: 1;\n }\n\n .uk-input\n {\n min-width:60px\n }\n #ScriptHeaderResources, #ScriptHeaderProgress\n {\n border-bottom-width: 1px;\n border-bottom-style: solid;\n border-bottom-color: rgb(221, 221, 221);\n background-color: rgb(255, 255, 255);\n display: flex;\n padding:10px\n }\n\n\n .table-row {\n display: flex;\n justify-content: flex-start;\n align-items: stretch;\n flex-wrap: nowrap;\n padding-top: 0px;\n padding-bottom: 10px;\n }\n\n .table-cell {\n min-height: 25px;\n flex-grow: 1;\n flex-basis: 100%;\n }\n\n #ResourcesTabsHeader {\n display: flex;\n margin-bottom: 0px;\n }\n\n #TabResources {\n margin-left: 3px;\n }\n\n #ResourcesTabsContent\n {\n margin-top: 0px;\n }\n\n #GlobalTabsHeader\n {\n margin-bottom: 0px;\n margin-top: 0px;\n }\n\n #ResourcesTabsContent\n {\n padding-top:0px\n }\n\n [uk-alert]\n {\n font-size: small\n }\n\n .resource-label\n {\n margin-bottom:5px\n }\n\n .row {\n display: flex;\n justify-content: flex-start;\n align-items: stretch;\n flex-wrap: nowrap;\n padding-top: 10px;\n padding-right: 10px;\n padding-bottom: 10px;\n padding-left: 10px;\n }\n\n .cell {\n min-height: 25px;\n flex-grow: 1;\n flex-basis: 100%;\n }\n\n .tab-not-valid\n {\n border-left: 2px solid red;\n }\n\n .uk-tab-left > *, .uk-tab-right > * {\n margin-bottom: 5px;\n }\n \n .tab-not-visible\n {\n display:none\n }\n\n .resource-not-visible\n {\n display:none\n }\n\n .spinner {\n width: 10px;\n height: 10px;\n background-color: #1e87f0;\n \n float: left;\n margin-top: 6px;\n margin-right: 4px;\n\n border-radius: 100%; \n -webkit-animation: sk-scaleout 1.0s infinite ease-in-out;\n animation: sk-scaleout 1.0s infinite ease-in-out;\n }\n\n#drop_file {\n border: 2px dashed #ccc;\n border-radius: 20px;\n width: 280px;\n font-family: sans-serif;\n margin: 20px auto;\n padding: 20px;\n}\n#drop_file.highlight {\n border-color: purple;\n}","html":"\n
\n \n \n
\n \n
\n
\n\n \n\n
\n
\n\n\n\n
\n
\n\n \n\n
\n
\n "}