Listing a folder structure in Classic ASP - asp-classic

I've developed a secure page in ASP for the company I work for. There is a landing (login page) that once you are authenticated you are taken to a page that has links to several sub pages. Each sub page has a folder structure. For example: There is a heading for Meeting Minutes and then underneath and indented are links referencing PDFs that contain the information. There may be 3 or 4 headings with documents linked beneath.
The original version had a PHP script that ran and would sync up the live site on the server from a folder structure that would be mimicked onto the live site. So if I had a folder called Folder1 and sub folders named test1 test2 test3.. the live site would display them accordingly. Since the site is now in ASP and not PHP.. the PHP script no longer works (since PHP doesn't play well with ASP).
I found a snippet online that somewhat works for what i'm trying to achieve (i.e. Folder/Subfolder/File Name structure), however i'm stuck at the moment with how to link the files so they open when clicked. I keep seeing a %25 in the file name. I know %20 is the same as a blank space and since I am dealing with file and folder names that contain spaces, this appears to be my issue. I've tried adding in a %20 but the spaces become "%2520".
If you look at the code below, there is a link towards the bottom that calls "MapURL". I have that link commented out at the moment as I was trying to figure out where the %25 was coming from.
Anyone have any thoughts on how to get the links to work?
Here is the snippet.
dim path
path = "PATH TO THE FOLDER ON THE SERVER"
ListFolderContents(path)
sub ListFolderContents(path)
dim fs, folder, file, item, url
set fs = CreateObject("Scripting.FileSystemObject")
set folder = fs.GetFolder(path)
'Display the target folder and info.
Response.Write("<ul><b>" & folder.Name & "</b>") '- " _
' & folder.Files.Count & " files, ")
'if folder.SubFolders.Count > 0 then
' Response.Write(folder.SubFolders.Count & " directories, ")
'end if
'Response.Write(Round(folder.Size / 1024) & " KB total." _
' & "</ul>" & vbCrLf)
Response.Write("<ul>" & vbCrLf)
'Display a list of sub folders.
for each item in folder.SubFolders
ListFolderContents(item)
next
'Display a list of files.
for each item in folder.Files
'url = MapURL(item.path)
'Response.Write("<li>" & item.Name & " - " _
Response.Write("<li>" & item.Name & " - " _
& item.Name & "</a>" _
& "</li>" & vbCrLf)
next
Response.Write("</ul>" & vbCrLf)
Response.Write("</ul>" & vbCrLf)
end sub
function MapURL(path)
dim rootPath, url
'Convert a physical file path to a URL for hypertext links.
rootPath = Server.MapPath("/")
url = Right(path, Len(path) - Len(rootPath))
MapURL = Replace(url, "\", "/")
end function

There are several things wrong with your code.
First and foremost, you do not encode the values you output at all. This is a big mistake. You are missing URL-encoding for things that go into the HREF attribute, and you miss HTML-encoding for everything else.
Next, you create a new FileSystemObject with every call to the recursive ListFolderContents() function. This is unnecessarily wasteful and will become slow as soon as there are more than a handful of files to be output.
Your recursive function should take a Folder object as the first argument, not a path. This makes things a lot easier.
The HTML structure you output is invalid. <b> cannot legally be a child of <ul>.
I completely rewrote your code to produce more correct output and to be as fast as possible. Crucial to your problem is the PathEncode() function, it transforms a relative path to a properly encoded URL. The other things should be pretty self-explanatory:
ListFolder "P:\ATH\TO\THE\FOLDER\ON\THE\SERVER"
' -- Main Functions ----------------------------------------------------
Sub ListFolder(path)
Dim fs, rootPath
Set fs = CreateObject("Scripting.FileSystemObject")
rootPath = Replace(path, Server.MapPath("/"), "") & "\"
ListFolderContents fs.GetFolder(path), PathEncode(rootPath)
End Sub
' ----------------------------------------------------------------------
Sub ListFolderContents(folder, relativePath)
Dim child
Say "<ul>"
Say "<li><div class=""folder"">" & h(folder.Name) & "</div>"
For Each child In folder.SubFolders
If Not IsHidden(child) Then
ListFolderContents child, relativePath & PathEncode(child.Name) & "/"
End If
Next
relativePath = h(relativePath)
For Each child In folder.Files
If Not IsHidden(child) Then
Say "<li>" & h(child.Name) & "</li>"
End If
Next
Say "</ul>"
End Sub
' -- Helper Functions / Shorthands ---------------------------------------
Sub Say(s)
Response.Write s & vbNewLine
End Sub
Function h(s)
h = Server.HTMLEncode(s)
End Function
Function PathEncode(s)
' this creates a more correct variant of what Server.URLEncode would do
PathEncode = Replace(s, "\", "/")
PathEncode = Server.URLEncode(PathEncode)
PathEncode = Replace(PathEncode, "+", "%20")
PathEncode = Replace(PathEncode, "%2F", "/")
PathEncode = Replace(PathEncode, "%2E", ".")
PathEncode = Replace(PathEncode, "%5F", "_")
End Function
Function IsHidden(File)
IsHidden = File.Attributes And 2 = 2
End Function
Notes
Use the <div class="folder"> to apply CSS styles (i.e. bold etc.) to the folder name.
The function will not output hidden files or directories.
The relativePath argument is used to keep the workload as low as possible - when a folder has 1000 files, it makes no sense to calculate the entire relative path 1000 times. With the help of this parameter, only the part that actually changes is processed.
Having functions like Say() or h() around can save you a lot of typing and it keeps the code more clean, too.
You should read up on URL-encoding (and HTML-encoding as well). Seems like you've never come across these things, which is especially bad if your task is to build a secure site.

you probably need extra quotes at the href (""). The best way is to see the generated source code (from the resulting page) like <a href=""" & replace(...) & """>"
Basically, if you use only one quote it just closes the string, but you are missing the HTML quote needed after href= and the closing one.

Related

Web Scraping by XMLHTTP

I would like to web scraping all the job title and company name from a job search website. However I unable to do so as I believe I cant inspect the correct element in the HTML codes. I researched this for days, please assist and advise on the correct HTML element. Once I able to inspect the correct element and I will do the looping and finish this program. Appreciate.
Website: https://www.efinancialcareers.my/search/?countryCode=MY&radius=40&radiusUnit=km&page=1&pageSize=20&currencyCode=MYR&language=en0
Option Explicit
Sub xmlhttp_scraping()
Dim XMLrequest As New MSXML2.XMLHTTP60
XMLrequest.Open "GET", "https://www.efinancialcareers.my/search/?countryCode=MY&radius=40&radiusUnit=km&page=1&pageSize=20&currencyCode=MYR&language=en0", False
XMLrequest.send
Dim iDOC As New MSHTML.HTMLDocument
iDOC.body.innerHTML = XMLrequest.responseText
'Cells(2, 2).Value = iDOC.getElementsByClassName("d-flex justify-content-between")(0).getElementsByTagName("h5")(0).getElementsByTagName("a")(0).innerText
'Cells(2, 2).Value = iDOC.getElementById("8091724").innerText
'Cells(2, 2).Value = iDOC.getElementsByClassName("search-card")(0).getElementsByClassName("d-flex justify-content-between")(0).getElementsByTagName("h5")(0).getElementsByTagName("a")(0).innerText
Range("H1").Value = "Time Updated on"
Range("I1").Value = Now
Columns.AutoFit
MsgBox "Done"
End Sub
Sample of HTML code below:
The page you try to get creates the contents using JavaScript. However, in your code, innerHTML of iDOC is only static content.
For the page to property run JavaScript, you can automate IE using InternetExplorer.Application. Try googling keywords like "Automate Internet Explorer Using VBA."
EDIT
I read your comment. The page gets the READY state too quickly. So, you should wait for the contents to be generated in some way (e.g. sleep or check some element appeared).
Public Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
Sub sc2()
Dim objIE As New InternetExplorer
objIE.Visible = True
objIE.navigate "https://www.efinancialcareers.my/search/?countryCode=MY&radius=40&radiusUnit=km&page=1&pageSize=20&currencyCode=MYR&language=en0"
Do While objIE.Busy = True Or objIE.readyState < READYSTATE_COMPLETE
DoEvents
Loop
Dim htmlDoc As HTMLDocument
' Wait long enough
Sleep 10000
' ... Or wait until some element appears (some element disappears)
' Do
' Set htmlDoc = objIE.document
'
' If htmlDoc.getElementsXXX Then
' Exit Do
' End If
'
' DoEvents
' Sleep 1000
' Loop
Set htmlDoc = objIE.document
' Then you can access elements
' ... but this code also has a problem. ``.getElementsByTagName("h5")`` returns nothing. Please inspect the html.
Debug.Print htmlDoc.getElementsByClassName("d-flex justify-content-between")(0).getElementsByTagName("h5")(0).getElementsByTagName("a")(0).innerText
End Sub
Moreover, the code that accesses the elements also has a problem. Since it doesn't follow generated html, .getElementsByTagName("h5") returns nothing. Please inspect the html in Chrome's console or VBE's Watch window.
== $0 is not related to your problem. It simply means the active DOM element in the developer tool. (What does == $0 mean in the DOM view in developer tools?)
By the way, more and more sites are dropping support for IE. Using InternetExplorer object is convenient, but automating Chrome or Firefox with Selenium is a better approach.

How do I set the width for an IMG when streaming out to MS Word from ASP.Net 4.0?

I'm streaming out to MS Word a document in HTML. It's working fine and the document downloads and opens in Word as expected. However, I'm on to my next trick and I want to include an Image in the file. I don't know the exact size of the image, however, as it is variable based on the users upload. So, I tried setting the image width as follows IMG Width=100px ... but the image came into word at full size. I also tried IMG style="width:100px" ... but the same result. I also tried IMG style="width:10%" ... same problem. I went to google but couldn't find anything useful on this. Thought I would try reaching out to you folks. Does anyone happen to know to set the width of an image when streaming to an MS Word document?
I also as a test took the output of the html string that gets sent to word, and put it in notpad, saved it as an htm file and took a look. It's formatted correctly and the image is the correct size there. So this seems to be something specific with how word handles image sizes, maybe?
Edit: note that in my example below I am only showing the relevant HTML ... but the actual HTML sent out is correctly formatted with html and body tags and so on.
The code I am using looks like this:
Sub PrintItem()
PrintToWord(strPrintOut)
End Sub
Function strPrintOut() as String
If CTR.ImagePath <> "None" Then
Dim PrintCTRImage As String = ""
PrintCTRImage = "<table width=15%><tr><td><IMG style=""height:100px;float:left;"" SRC=" & Chr(34) & MySession.BC.GetIMGPath(CTR.ImagePath, True, pg) & Chr(34) & "></td></tr></table>"
strCTRt &= PrintCTRImage
End If
strPrintOut = strCTRt
End Function
Public Sub PrintToWord(ByVal strPrintOut As String, ByVal FileName As String, ByVal pg As Page)
Try
Dim bString() As Byte
bString = StrToByteArray(strPrintOut)
pg.Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", FileName & ".doc"))
pg.Response.Charset = Encoding.UTF8.WebName
pg.Response.Cache.SetCacheability(HttpCacheability.NoCache)
pg.Response.BinaryWrite(bString)
pg.Response.Flush()
pg.Response.End()
HttpContext.Current.ApplicationInstance.CompleteRequest()
Catch ex As System.Threading.ThreadAbortException
Catch ex As Exception
MySession.BC.HandleMessage(ex, pg)
End Try
End Sub
Ok ... hunting and pecking randomly I found an unrelated post that clued me into the answer. The code the build the image tag string should look like this:
PrintCharacterImage = "<HR><IMG width=""120"" Height=""120"" style=""float:left;Margin:12px;"" SRC=" & Chr(34) & MySession.BC.GetIMGPath(Character.ImagePath, True, pg) & Chr(34) & ">"

Cannot make Access 2010 accde from Access 2007 accdb

I have a bit of a problem and could really use some help. My organization recently migrated from Office 2007 to Office 2010. I had a database that I developed using Access 2007 (using the .accdb database file type). Throughout the migration process, I was still making updates to my database. All the updates were made via an Office 2007 machine and everything worked on the 2010 systems that I deployed it to, as well as the 2007 boxes. The problem now is that since all the computers are officially on 2010, I cannot seem to create an Accde file from Access 2010. The error I receive is: " The command or action 'MakeMDEFile' isn't available now." * You may be in a read-only database or an unconverted database from an earlier version..." The code is compiled with no errors and my references are good. I have tried to re-compile the code, re-name the wizards in the "C:\Program Files\Microsoft Office\Office14\ACCWIZ" folder and let them re-install, and import all my objects into a new database based on this article: http://msdn.microsoft.com/library/office/dn602608%28v=office.14%29.aspx; all to no avail.I do not have any web content or anything Access 2010 specific, as I only made adjustments to the things I created in 2007. I did read that Access must be compiled on the same version that it was created on, but I thought since both 2007 and 2010 use the .accdb file format it would be compatible? Any advice on this? Thank you.
Thank you for your quick answer! That worked great. I was able to successfully export my DB using the code and I also imported all the objects with the exception of the queries. (I was able to create the accde.) Because I have so many objects, I used a script to import everything. The problem I am experiencing now is with my SQL queries. The export script named the text files a little different for the SQL queries and I don't know how to handle them. Below is my code that worked for the rest of the objects:
Public Sub batchImport_queries()
On Error GoTo batchImport_Err
Dim objFS As Object, objFolder As Object
Dim objFiles As Object, objF1 As Object
Dim strFolderPath As String
strFolderPath = "C:\Users\Me\Desktop\dbexport\queries\"
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFS.GetFolder(strFolderPath)
Set objFiles = objFolder.files
For Each objF1 In objFiles
objF1.Name = Right(objF1.Name, Len(objF1.Name) - 6)'strips "Query_"
objF1.Name = Left(objF1.Name, Len(objF1.Name) - 3) 'strips ".txt"
Application.Application.LoadFromText acQuery, objF1.Name, strFolderPath & objF1.Name
Next
Set objF1 = Nothing
Set objFiles = Nothing
Set objFolder = Nothing
Set objFS = Nothing
batchImport_Exit:
Exit Sub
batchImport_Err:
MsgBox Err.Number & " " & Err.Description
Resume batchImport_Exit
End Sub
That worked for queries like: "Query_qryAvailable.txt" but the SQL ones look like this: "Query_~sq_cCIPSSubform~sq_RosterSubform.txt". It seems to be encapsulating "~sq_c" around the first part of the query name and then the form/subform/or control that is associated with it at the last part of the filename...or I could be completely off. I can't figure out the pattern. Some of them have "~sq_f" instead, only at the leading part.(I'm guessing those are for forms?) Anyway, is there a better way to format the file name (if that's what has to be done) to remove those to my original query names and import correctly? Please let me know if that doesn't make sense. Thank you for your time.
It's possible to export an Access database to text files, see here: http://www.access-programmers.co.uk/forums/showthread.php?t=99179.
Option Compare Database
Option Explicit
Public Sub ExportDatabaseObjects()
On Error GoTo Err_ExportDatabaseObjects
Dim db As Database
'Dim db As DAO.Database
Dim td As TableDef
Dim d As Document
Dim c As Container
Dim i As Integer
Dim sExportLocation As String
Set db = CurrentDb()
sExportLocation = "C:\Temp\" 'Do not forget the closing back slash! ie: C:\Temp\
For Each td In db.TableDefs 'Tables
If Left(td.Name, 4) <> "MSys" Then
DoCmd.TransferText acExportDelim, , td.Name, sExportLocation & "Table_" & td.Name & ".txt", True
End If
Next td
Set c = db.Containers("Forms")
For Each d In c.Documents
Application.SaveAsText acForm, d.Name, sExportLocation & "Form_" & d.Name & ".txt"
Next d
Set c = db.Containers("Reports")
For Each d In c.Documents
Application.SaveAsText acReport, d.Name, sExportLocation & "Report_" & d.Name & ".txt"
Next d
Set c = db.Containers("Scripts")
For Each d In c.Documents
Application.SaveAsText acMacro, d.Name, sExportLocation & "Macro_" & d.Name & ".txt"
Next d
Set c = db.Containers("Modules")
For Each d In c.Documents
Application.SaveAsText acModule, d.Name, sExportLocation & "Module_" & d.Name & ".txt"
Next d
For i = 0 To db.QueryDefs.Count - 1
Application.SaveAsText acQuery, db.QueryDefs(i).Name, sExportLocation & "Query_" & db.QueryDefs(i).Name & ".txt"
Next i
Set db = Nothing
Set c = Nothing
MsgBox "All database objects have been exported as a text file to " & sExportLocation, vbInformation
Exit_ExportDatabaseObjects:
Exit Sub
Err_ExportDatabaseObjects:
MsgBox Err.Number & " - " & Err.Description
Resume Exit_ExportDatabaseObjects
End Sub
If the principle still holds, you should be able to import the resulting objects to a fresh database. If there are any problems with permissions, that should become evident in the text files, but normally this strips all permissions.

asp fileExists always returning false

Trying to use a loop to check if images exists however it is always returning false. I am sure I am doing something simple and stupid but here is the code:
dim fs, sql_except
set fs=Server.CreateObject("Scripting.FileSystemObject")
if Not rs.eof then
arrRS = rs.GetRows(30,0)
set rs = nothing
If IsArray(arrRS) Then
For i = LBound(arrRS, 2) to UBound(arrRS, 2)
sku = arrRS(0, i)
if (fs.FileExists("../i/"&sku&".gif")=false) Then
response.write sku&"does not exist<br>"
end if
next
end if
erase arrRS
end if
set fs=nothing
You appear to be operating under the impression that the current folder context the your call to FileExists will assume is the physical folder containing the ASP script being executed. This is not so, it most likely will be "C:\windows\system32\inetsrv". You are also using URL path element separator / where FileExists is expecting windows physical path folder separator \.
You need to use Server.MapPath to resolve the path. This may work:
if Not fs.FileExists(Server.MapPath("../i/"&sku&".gif")) then
However you may run in to trouble with the parent path "..", this may not be allowed for security reasons. This might be a better approach:
Dim path : path = Server.MapPath("/parentFolder/i") & "\"
For i = LBound(arrRS, 2) to UBound(arrRS, 2)
sku = arrRS(0, i)
if Not fs.FileExists(path & sku & ".gif") Then
response.write Server.HTMLEncode(sku) & " does not exist<br>"
end if
next
Where "parentFolder" is the absolute path from the site root.

vbscript / Classic ASP - Is there any way to get your own file name programmatically?

I was just reviewing some old code and found the following (inside foo.asp):
Const ASP_FILENAME = "foo.asp" ' TODO: Update this to the name of this file (if changed)
The variable is only used for logging errors. (ie. "Error in foo.asp - Could not create xxxxx object.") Is there any way to avoid this?
Thanks!
You could parse Request.ServerVariables("url") to get the filename portion. A google search found this code, to which i don't claim credit, which uses the SCRIPT_NAME server variable which seems to make more sense indeed, also taking any url rewriting in to account that might be in place:
function getFileName(fpath, returnExtension)
tmp = fpath
if instrRev(tmp,"/") > 0 then
tmp = mid(tmp, instrRev(tmp,"/")+1)
end if
if returnExtension = false then
if instrRev(tmp,".") > 0 then
tmp = left(tmp, instrRev(tmp,".")-1)
end if
end if
getFileName = tmp
end function
filename = request.ServerVariables("SCRIPT_NAME")
Const ASP_FILENAME = getFileName(filename, true)
From the now-defunct Aspfaq.com (thanks to Archive.org):
How do I get the name of the current URL / page?
This one is pretty easy, but there are two parts.
To retrieve the name of the current file, you can use any of these:
<%
Response.Write Request.ServerVariables("SCRIPT_NAME") & "<br>"
Response.Write Request.ServerVariables("PATH_INFO") & "<br>"
Response.Write Request.ServerVariables("URL") & "<br>"
%>
To make that path local (for example, to use with FileSystemObject), just apply the server.mappath() method to the result.
To get the entire URL, including the http:// or https:// prefix, you can do this:
<%
prot = "http"
https = lcase(request.ServerVariables("HTTPS"))
if https <> "off" then prot = "https"
domainname = Request.ServerVariables("SERVER_NAME")
filename = Request.ServerVariables("SCRIPT_NAME")
querystring = Request.ServerVariables("QUERY_STRING")
response.write prot & "://" & domainname & filename & "?" & querystring
%>
To get the page name ONLY, use something like this:
<%
scr = Request.ServerVariables("SCRIPT_NAME") & "<br>"
if instr(scr,"/")>0 then
scr = right(scr, len(scr) - instrRev(scr,"/"))
end if
response.write scr
%>
Or, without the IF logic:
<%
scr = Request.ServerVariables("SCRIPT_NAME") & "<br>"
loc = instrRev(scr,"/")
scr = mid(scr, loc+1, len(scr) - loc)
response.write scr
%>
Now. If your file is an #INCLUDE within another file, the above scripts will produce the name of the CALLING file (since the included file is first integrated into the calling script, then the ASP within it is all executed in the context of the 'parent' file). One way you can work around this is to re-populate a current_filename variable before loading each include file, for example:
<%
current_filename = "filetoinclude.asp"
%>
<!--#include file='filetoinclude.asp'-->
(And no, don't try passing current_filename as a variable to the #INCLUDE directive; see Article #2042.)
Then, in filetoinclude.asp:
<%
Response.Write "Current file: " & current_filename
%>
Of course, you could just as easily hard-code the filename inside of each include file. But I suppose that solution would somewhat defeat the purpose of retrieving that information at least somewhat dynamically.
I dont know if server.mappath exists on traditional asp, but if so you could use if to know the page filename.
Not saying that anyone here [insert discrete throat clearing cough here] still uses Classic ASP for maintaining and supporting legacy applications, but I recently had the need to do something similar. Refusing to settle for the "it's impossible with Classic ASP" responses out there, I set out to find a way and came up with the following solution.
This approach basically leverages underlying OS commands to literally determine the current filename (whose result is equivalent to using the __FILE__ magic constant in PHP) regardless of whether it's a file include (*.inc) or the script itself (*.asp).
First, to support some sanitization (you can do this some other more "optimal" way if you wish):
'Regex helpers
Function NewRegex(ByVal pattern, ByVal ignore_case, ByVal global)
Set NewRegex = New RegExp
NewRegex.Pattern = pattern
NewRegex.IgnoreCase = ignore_case
NewRegex.Global = global
End Function
Function RegexMatch(ByVal pattern, ByVal subject)
RegexMatch = RegexMatches(subject, pattern, True, False)
End Function
Function RegexMatches(ByVal subject, ByVal pattern, ByVal ignore_case, ByVal global)
RegexMatches = NewRegex(pattern, ignore_case, global).Test(subject)
End Function
And now for a time of "reflection:"
Function GetCurrentFilename(ByVal uniqueId)
'1. Enforce uniqueId format
If Not RegexMatch("^[0-9a-f]+$", uniqueId) Then
Exit Function
End If
'2. Use findstr to scan "readable" files in current directory for uniqueId
Dim shell, cmd, process, fs, filename
Set shell = Server.CreateObject("WScript.Shell")
'See findstr /? for details on switches used below
'cmd = C:\Windows\system32\cmd.exe /c findstr /P /M /C:"uniqueId" "C:\Inetpub\wwwroot\includes\*"
cmd = shell.ExpandEnvironmentStrings("%COMSPEC%") & " /c findstr /P /M /C:""" & uniqueId & """ """ & Server.MapPath(".") & "\*"""
Set process = shell.Exec(cmd)
'3. Use Scripting.FileSystemObject to return the filename portion of the first result returned
Set fs = Server.CreateObject("Scripting.FileSystemObject")
GetCurrentFilename = fs.GetFileName(process.StdOut.ReadLine())
Set fs = Nothing
Set process = Nothing
Set shell = Nothing
End Function
Then, inside whatever file you want to "inspect" the current filename, simply drop the following line, passing in some unique identifier that should not exist in any other file in the current directory but this one:
'myfile.inc
Response.Write "This is in " & GetCurrentFilename("908ab098c")
The result:
This is in somefile.inc
Oh, and if you're interested in what I needed to use this for, here's what it looks like used in a simple breakpoint function:
Function Breakpoint(ByVal line_no, ByVal uniqueId, ByVal msg)
Dim fn
fn = GetCurrentFilename(uniqueId)
Response.Write "[!] Breakpoint hit at Line " & CLng(line_no) & " in " & fn & ": " & Server.HtmlEncode(msg) & vbNewLine
Response.End
End Function
Such that on Line 20 of my code, if I wanted to add my own breakpoint, it would look like this:
Breakpoint 20, "B0001", "Some debug output here"
Output:
[!] Breakpoint hit at Line 20 in somefile.inc: Some debug output here
Happy coding!

Resources