Addons
  • Uploaded By: westor
  • Author: SReject
  • Added: 1 year ago
  • Updated: 1 year ago
  • mIRC Version: 7.48+
  • Hits: 895
  • Size: 8.29KB
  • Downloads: 30
  • Review By: westor

JSON For mIRC 1.0.4000

A script to parse and then access JSON from within mIRC.

"But Mr. Reject, there's plenty of these scripts! Why create another?" Well, little one, I find that most of those scripts trade in efficiency for simplicity. Generally speaking most JSON scripts for mIRC reparse the json data each time that data needs to be accessed.

My version, though a bit more complex to understand, only requires the parsing of JSON data once per JSON handler instance, making it quite a bit faster and less resource intensive to use. Along with being a bit more efficient handling JSON, the script can retrieve data from remote sources for parsing. Allowing for the request method and headers to be set as needed.

"But why a JSON parser? Why not spend your time coding something that the typical user would make use of?". Its simple, to make those fancy GUI-intensive scripts, scripters need/use tools to simplify the tasks. This is one such tool.

The reason for a JSON parser vs. some other 'tool' is because of its overwhelming use around the web. Now-a-days, when you want data from a website they probably package it as an API that generally returns results in JSON format. Examples include: Google.com, Youtube.com, Pastebin.com, and Weather.com

Requirements
Win XP or later (This will not work under WINE)
mIRC v7.48 or later OR AdiIRC v2.8 or later
If using AdiIRC 64bit tsc64.dll needs to be installed

Official Github: https://github.com/SReject/JSON-For-Mirc

  
  4    0  Login to Vote.


Source Code:
  1. #SReject/JSONForMirc/CompatMode off
  2. alias JSONUrlMethod {
  3. if ($isid) return
  4. JSONHttpMethod $1-
  5. }
  6. alias JSONUrlHeader {
  7. if ($isid) return
  8. JSONHttpHeader $1-
  9. }
  10. alias JSONUrlGet {
  11. if ($isid) return
  12. JSONHttpFetch $1-
  13. }
  14. #SReject/JSONForMirc/CompatMode end
  15. on *:LOAD:{
  16. JSONShutdown
  17. if ($~adiircexe) {
  18. if ($version < 2.8) {
  19. echo -ag [JSON For mIRC] AdiIRC v2.7 beta 01/28/2016 or later is required
  20. .unload -rs $qt($script)
  21. }
  22. }
  23. elseif ($version < 7.48) {
  24. echo -ag [JSON For mIRC] mIRC v7.48 or later is required
  25. .disable #SReject/JSONForMirc/CompatMode
  26. .unload -rs $qt($script)
  27. }
  28. }
  29. on *:START:JSONShutDown
  30. on *:CLOSE:@SReject/JSONForMirc/Log:if $jsondebug { jsondebug off }
  31. on *:EXIT:JSONShutDown
  32. on *:UNLOAD:{
  33. .disable #SReject/JSONForMirc/CompatMode
  34. JSONShutDown
  35. }
  36. menu @SReject/JSONForMirc/Log {
  37. .$iif(!$jfm_SaveDebug,$style(2)) Clear: clear -@ $active
  38. .-
  39. .$iif(!$jfm_SaveDebug,$style(2)) Save: jfm_SaveDebug
  40. .-
  41. .Toggle Debug:jsondebug
  42. .-
  43. .Close:jsondebug off | close -@ $active
  44. }
  45. alias JSONOpen {
  46. if ($isid) return
  47. if ($hget(SReject/JSONForMirc,Error)) hdel SReject/JSONForMirc Error
  48. var %Switches,%Error,%Com $false,%Type text,%HttpOptions 0,%BVar,%BUnset $true
  49. jfm_log -I /JSONOpen $1-
  50. if (-* iswm $1) {
  51. %Switches = $mid($1,2-)
  52. tokenize 32 $2-
  53. }
  54. if ($jfm_ComInit) %Error = $v1
  55. elseif (!$regex(SReject/JSONOpen/switches,%Switches,^[dbfuUw]*$)) %Error = SWITCH_INVALID
  56. elseif ($regex(%Switches,([dbfuUw]).*?\1)) %Error = SWITCH_DUPLICATE: $+ $regml(1)
  57. elseif ($regex(%Switches,/([bfuU])/g) > 1) %Error = SWITCH_CONFLICT: $+ $regml(1)
  58. elseif (u !isin %Switches) && (w isincs %Switches) { %Error = SWITCH_NOT_APPLICABLE:w }
  59. elseif ($0 < 2) %Error = PARAMETER_MISSING
  60. elseif ($regex($1,/(?:^\d+$)|[*:? ]/i)) %Error = NAME_INVALID
  61. elseif ($com(JSON: $+ $1)) %Error = NAME_INUSE
  62. elseif (u isin %Switches) && ($0 != 2) { %Error = PARAMETER_INVALID:URL_SPACES }
  63. elseif (b isincs %Switches) && ($0 != 2) { %Error = PARAMETER_INVALID:BVAR }
  64. elseif (b isincs %Switches) && (&* !iswm $2) { %Error = PARAMETER_INVALID:NOT_BVAR }
  65. elseif (b isincs %Switches) && (!$bvar($2,0)) { %Error = PARAMETER_INVALID:BVAR_EMPTY }
  66. elseif (f isincs %Switches) && (!$isfile($2-)) { %Error = PARAMETER_INVALID:FILE_DOESNOT_EXIST }
  67. else {
  68. %Com = JSON: $+ $1
  69. %BVar = $jfm_TmpBVar
  70. if (b isincs %Switches) {
  71. %Bvar = $2
  72. %BUnset = $false
  73. }
  74. elseif (u isin %Switches) {
  75. if (w isincs %Switches) inc %HttpOptions 1
  76. if (U isincs %Switches) inc %HttpOptions 2
  77. %Type = http
  78. bset -t %BVar 1 $2
  79. }
  80. elseif (f isincs %Switches) bread $qt($file($2-).longfn) 0 $file($file($2-).longfn).size %BVar
  81. else bset -t %BVar 1 $2-
  82. jfm_ToggleTimers -p
  83. %Error = $jfm_Create(%Com,%Type,%BVar,%HttpOptions)
  84. jfm_ToggleTimers -r
  85. }
  86. :error
  87. if ($error) %Error = $v1
  88. reseterror
  89. if (%BUnset) bunset %BVar
  90. if (%Error) {
  91. hadd -mu0 SReject/JSONForMirc Error %Error
  92. if (%Com) && ($com(%Com)) { .timer $+ %Com -iom 1 0 JSONClose $unsafe($1) }
  93. jfm_log -EeDF %Error
  94. }
  95. else {
  96. if (d isincs %Switches) .timer $+ %Com -iom 1 0 JSONClose $unsafe($1)
  97. jfm_log -EsDF Created $1 (as com %Com $+ )
  98. }
  99. }
  100. alias JSONHttpMethod {
  101. if ($isid) return
  102. if ($hget(SReject/JSONForMirc,Error)) hdel SReject/JSONForMirc Error
  103. var %Error,%Com,%Method
  104. jfm_log -I /JSONHttpMethod $1-
  105. if ($jfm_ComInit) %Error = $v1
  106. elseif ($0 < 2) %Error = PARAMETER_MISSING
  107. elseif ($0 > 2) %Error = PARAMETER_INVALID
  108. elseif ($regex($1,/(?:^\d+$)|[*:? ]/i)) %Error = NAME_INVALID
  109. elseif (!$com(JSON: $+ $1)) %Error = HANDLE_DOES_NOT_EXIST
  110. else {
  111. %Com = JSON: $+ $1
  112. %Method = $regsubex($2,/(^\s+)|(\s*)$/g,)
  113. if (!$len(%Method)) %Error = INVALID_METHOD
  114. elseif ($jfm_Exec(%Com,httpSetMethod,%Method)) %Error = $v1
  115. }
  116. :error
  117. if ($error) %Error = $v1
  118. reseterror
  119. if (%Error) {
  120. hadd -mu0 SReject/JSONForMirc Error %Error
  121. jfm_log -EeDF %Error
  122. }
  123. else jfm_log -EsDF Set Method to $+(',%Method,')
  124. }
  125. alias JSONHttpHeader {
  126. if ($isid) return
  127. if ($hget(SReject/JSONForMirc,Error)) hdel SReject/JSONForMirc Error
  128. var %Error,%Com,%Header
  129. jfm_log -I /JSONHttpHeader $1-
  130. if ($jfm_ComInit) %Error = $v1
  131. elseif ($0 < 3) %Error = PARAMETER_MISSING
  132. elseif ($regex($1,/(?:^\d+$)|[*:? ]/i)) %Error = INVALID_NAME
  133. elseif (!$com(JSON: $+ $1)) %Error = HANDLE_DOES_NOT_EXIST
  134. else {
  135. %Com = JSON: $+ $1
  136. %Header = $regsubex($2,/(^\s+)|(\s*:\s*$)/g,)
  137. if (!$len($2)) %Error = HEADER_EMPTY
  138. elseif ($regex($2,[
  139. :
  140. ])) %Error = HEADER_INVALID
  141. elseif ($jfm_Exec(%Com,httpSetHeader,%Header,$3-)) %Error = $v1
  142. }
  143. :error
  144. if ($error) %Error = $v1
  145. reseterror
  146. if (%Error) {
  147. hadd -mu0 SReject/JSONForMirc Error %Error
  148. jfm_log -EeDF %Error
  149. }
  150. else jfm_log -EsDF Stored Header $+(',%Header,: $3-,')
  151. }
  152. alias JSONHttpFetch {
  153. if ($isid) return
  154. if ($hget(SReject/JSONForMirc,Error)) hdel SReject/JSONForMirc Error
  155. var %Switches,%Error,%Com,%BVar,%BUnset
  156. jfm_log -I /JSONHttpFetch $1-
  157. if (-* iswm $1) {
  158. %Switches = $mid($1,2-)
  159. tokenize 32 $2-
  160. }
  161. if ($jfm_ComInit) %Error = $v1
  162. if ($0 == 0) || (%Switches != $null && $0 < 2) { %Error = PARAMETER_MISSING }
  163. elseif ($regex(%Switches,([^bf]))) %Error = SWITCH_INVALID: $+ $regml(1)
  164. elseif ($regex($1,/(?:^\d+$)|[*:? ]/i)) %Error = NAME_INVALID
  165. elseif (!$com(JSON: $+ $1)) %Error = HANDLE_DOES_NOT_EXIST
  166. elseif (b isincs %Switches) && (&* !iswm $2 || $0 > 2) { %Error = BVAR_INVALID }
  167. elseif (f isincs %Switches) && (!$isfile($2-)) { %Error = FILE_DOESNOT_EXIST }
  168. else {
  169. %Com = JSON: $+ $1
  170. if ($0 > 1) {
  171. %BVar = $jfm_tmpbvar
  172. %BUnset = $true
  173. if (b isincs %Switches) {
  174. %BVar = $2
  175. %BUnset = $false
  176. }
  177. elseif (f isincs %Switches) bread $qt($file($2-).longfn) 0 $file($2-).size %BVar
  178. else bset -t %BVar 1 $2-
  179. %Error = $jfm_Exec(%Com, httpSetData,& %BVar).fromBvar
  180. }
  181. if (!%Error) %Error = $jfm_Exec(%Com,parse)
  182. }
  183. :error
  184. if ($error) %Error = $error
  185. reseterror
  186. if (%BUnset) bunset %BVar
  187. if (%Error) {
  188. hadd -mu0 SReject/JSONForMirc Error %Error
  189. jfm_log -EeDF %Error
  190. }
  191. else jfm_log -EsDF Http Data retrieved
  192. }
  193. alias JSONClose {
  194. if ($isid) return
  195. if ($hget(SReject/JSONForMirc,Error)) hdel SReject/JSONForMirc Error
  196. var %Switches,%Error,%Match,%Com,%X 1
  197. jfm_log -I /JSONClose $1-
  198. if (-* iswm $1) {
  199. %Switches = $mid($1, 2-)
  200. tokenize 32 $2-
  201. }
  202. if ($0 < 1) %Error = PARAMTER_MISSING
  203. elseif ($0 > 1) %Error = PARAMETER_INVALID
  204. elseif ($regex(%Switches,/([^w])/)) %Error = SWITCH_UNKNOWN: $+ $regml(1)
  205. elseif (: isin $1) && (w isincs %Switches || JSON:* !iswmcs $1) { %Error = PARAMETER_INVALID }
  206. else {
  207. %Match = $1
  208. if (JSON:* iswmcs $1) %Match = $gettok($1,2-,58)
  209. %Match = $replacecs(%Match,\E,\E\\E\Q)
  210. if (w isincs %Switches) %Match = $replacecs(%Match,?,\E[^:]\Q,*,\E[^:]*\Q)
  211. %Match = /^JSON:\Q $+ %Match $+ \E(?::\d+)?$/i
  212. %Match = $replacecs(%Match,\Q\E,)
  213. while (%X <= $com(0)) {
  214. %Com = $com(%X)
  215. if ($regex(%Com,%Match)) {
  216. .comclose %Com
  217. if ($timer(%Com)) .timer $+ %Com off
  218. jfm_log Closed %Com
  219. }
  220. else inc %X
  221. }
  222. }
  223. :error
  224. if ($error) %Error = $error
  225. reseterror
  226. if (%Error) {
  227. hadd -mu0 SReject/JSONForMirc Error %Error
  228. jfm_log -EeD /JSONClose %Error
  229. }
  230. else jfm_log -EsD All matching handles closed
  231. }
  232. alias JSONList {
  233. if ($isid) return
  234. var %X 1,%I 0
  235. jfm_log /JSONList $1-
  236. while ($com(%X)) {
  237. if (JSON:?* iswm $v1) {
  238. inc %I
  239. echo $color(info) -age * $chr(35) $+ %I $+ : $v2
  240. }
  241. inc %X
  242. }
  243. if (!%I) echo $color(info) -age * No active JSON handlers
  244. }
  245. alias JSONShutDown {
  246. if ($isid) return
  247. JSONClose -w *
  248. if ($JSONDebug) JSONDebug off
  249. if ($window(@SReject/JSONForMirc/Log)) close -@ $v1
  250. if ($com(SReject/JSONForMirc/JSONEngine)) .comclose $v1
  251. if ($com(SReject/JSONForMirc/JSONShell)) .comclose $v1
  252. if ($hget(SReject/JSONForMirc)) hfree $v1
  253. }
  254. alias JSONCompat {
  255. if ($isid) return $iif($group(#SReject/JSONForMirc/CompatMode) == on, $true, $false)
  256. .enable #SReject/JSONForMirc/CompatMode
  257. }
  258. alias JSON {
  259. if (!$isid) return
  260. if ($hget(SReject/JSONForMirc, Error)) hdel SReject/JSONForMirc Error
  261. var %X,%Args,%Params,%Error,%Com,%I 0,%Prefix,%Prop,%Suffix,%Offset 2,%Type,%Output,%Result,%ChildCom,%Call
  262. if (*ToFile iswm $prop) %Offset = 3
  263. if ($JSONDebug) {
  264. %X = 1
  265. while (%X <= $0) {
  266. if (%Args !== $null) %Args = %Args $+ $chr(44)
  267. %Args = %Args $+ $($ $+ %X, 2)
  268. if (%X >= %Offset) %Params = %Params $+ ,bstr,$ $+ %X
  269. inc %X
  270. }
  271. }
  272. elseif ($0 >= %Offset) {
  273. %X = %Offset
  274. while (%x <= $0) {
  275. %Params = %Params $+ ,bstr,$ $+ %X
  276. inc %x
  277. }
  278. }
  279. jfm_log -I $!JSON( $+ %Args $+ ) $+ $iif($prop !== $null, . $+ $prop)
  280. if (!$0) || ($0 == 1 && $1 == $null) {
  281. %Error = PARAMETER_MISSING
  282. goto error
  283. }
  284. if ($0 == 1) && ($1 == 0) && ($prop !== $null) {
  285. %Error = PROP_NOT_APPLICABLE
  286. goto error
  287. }
  288. if ($regex(name,$1,/^JSON:[^:?*]+(?::\d+)?$/i)) %Com = $1
  289. elseif (: isin $1 || * isin $1 || ? isin $1) || ($1 == 0 && $0 !== 1) { %Error = INVALID_NAME }
  290. elseif ($1 isnum 0- && . !isin $1) {
  291. %X = 1
  292. while ($com(%X)) {
  293. if ($regex($v1,/^JSON:[^:]+$/)) {
  294. inc %I
  295. if (%I === $1) {
  296. %Com = $com(%X)
  297. break
  298. }
  299. }
  300. inc %X
  301. }
  302. if ($1 === 0) {
  303. jfm_log -EsDF %I
  304. return %I
  305. }
  306. }
  307. else %Com = JSON: $+ $1
  308. if (!%Error) && (!$com(%Com)) { %Error = HANDLER_NOT_FOUND }
  309. elseif (* isin $prop) || (? isin $prop) { %Error = INVALID_PROP }
  310. else {
  311. if ($regex($prop, /^((?:fuzzy)?)(.*?)((?:to(?:bvar|file))?)?$/i)) {
  312. %Prefix = $regml(1)
  313. %Prop = $regml(2)
  314. %Suffix = $regml(3)
  315. }
  316. %Prop = $regsubex(%Prop, /^url/i, http)
  317. if ($JSONCompat) {
  318. if (%Prop == status) %Prop = state
  319. if (%Prop == data) %Prop = input
  320. if (%Prop == isRef) %Prop = isChild
  321. if (%Prop == isParent) %Prop = isContainer
  322. }
  323. if (%Suffix == tofile) {
  324. if ($0 < 2) %Error = INVALID_PARAMETERS
  325. elseif (!$len($2) || $isfile($2) || (!$regex($2, /[\\\/]/) && " isin $2)) { %Error = INVALID_FILE }
  326. else %Output = $longfn($2)
  327. }
  328. }
  329. if (%Error) goto error
  330. elseif ($0 == 1) && (!$prop) {
  331. %Result = $jfm_TmpBvar
  332. bset -t %Result 1 %Com
  333. }
  334. elseif (%Prop == isChild) {
  335. %Result = $jfm_TmpBvar
  336. if (JSON:?*:?* iswm %com) bset -t %Result 1 $true
  337. else bset -t %Result 1 $false
  338. }
  339. elseif ($wildtok(state|error|input|inputType|httpParse|httpHead|httpStatus|httpStatusText|httpHeaders|httpBody|httpResponse,%Prop,1,124)) {
  340. if ($jfm_Exec(%Com,$v1)) %Error = $v1
  341. else %Result = $hget(SReject/JSONForMirc,Exec)
  342. }
  343. elseif (%Prop == httpHeader) {
  344. if ($calc($0 - %Offset) < 0) %Error = INVALID_PARAMETERS
  345. elseif ($jfm_Exec(%Com,httpHeader,$($ $+ %Offset,2))) %Error = $v1
  346. else %Result = $hget(SReject/JSONForMirc,Exec)
  347. }
  348. elseif (%Prop == $null) || ($wildtok(path|pathLength|type|isContainer|length|value|string|debug, %Prop, 1, 124)) {
  349. %Prop = $v1
  350. if ($0 >= %Offset) {
  351. %ChildCom = JSON: $+ $gettok(%Com,2,58) $+ :
  352. %X = $ticks $+ 000000
  353. while ($com(%ChildCom $+ %X)) inc %X
  354. %ChildCom = %ChildCom $+ %X
  355. %Call = $!com( $+ %Com $+ ,walk,1,bool, $+ $iif(fuzzy == %Prefix,$true,$false) $+ %Params $+ ,dispatch* %ChildCom $+ )
  356. jfm_log %Call
  357. if (!$eval(%Call, 2)) || ($comerr) || (!$com(%ChildCom)) {
  358. %Error = $jfm_GetError
  359. goto error
  360. }
  361. .timer $+ %ChildCom -iom 1 0 JSONClose %ChildCom
  362. %Com = %ChildCom
  363. jfm_log
  364. }
  365. if ($JSONCompat) && ($prop == $null) {
  366. if ($jfm_exec(%Com,type)) %Error = $v1
  367. elseif ($bvar($hget(SReject/JSONForMirc,Exec), 1-).text == object) || ($v1 == array) {
  368. %Result = $jfm_TmpBvar
  369. bset -t %Result 1 %Com
  370. }
  371. elseif ($jfm_Exec(%Com, value)) %Error = $v1
  372. else %Result = $hget(SReject/JSONForMirc,Exec)
  373. }
  374. elseif (!%Prop) {
  375. %Result = $jfm_TmpBvar
  376. bset -t %Result 1 %Com
  377. }
  378. elseif (%Prop !== value) {
  379. if ($jfm_Exec(%Com,$v1)) %Error = $v1
  380. else %Result = $hget(SReject/JSONForMirc,Exec)
  381. }
  382. elseif ($jfm_Exec(%Com,type)) %Error = $v1
  383. elseif ($bvar($hget(SReject/JSONForMirc,Exec),1-).text == object) || ($v1 == array) { %Error = INVALID_TYPE }
  384. elseif ($jfm_Exec(%Com,value)) %Error = $v1
  385. else %Result = $hget(SReject/JSONForMirc,Exec)
  386. }
  387. else %Error = UNKNOWN_PROP
  388. if (!%Error) {
  389. if (%Suffix == tofile) {
  390. bwrite $qt(%Output) -1 -1 %Result
  391. bunset %Result
  392. %Result = %Output
  393. }
  394. elseif (%Suffix !== tobvar) %Result = $bvar(%Result,1,4000).text
  395. }
  396. :error
  397. if ($error) %Error = $error
  398. reseterror
  399. if (%Error) {
  400. hadd -mu0 SReject/JSONForMirc Error %Error
  401. jfm_log -EeDF %Error
  402. }
  403. else {
  404. jfm_log -EsDF %Result
  405. return %Result
  406. }
  407. }
  408. alias JSONForEach {
  409. if (!$isid) return
  410. if ($hget(SReject/JSONForMirc,Error)) hdel SReject/JSONForMirc Error
  411. var %Error,%Log,%Call,%X 0,%JSON,%Com,%ChildCom,%Result 0,%Name
  412. %Log = $!JSONForEach(
  413. if ($prop == walk) %Call = ,forEach,1,bool,$true,bool,$false
  414. elseif ($prop == fuzzy) %Call = ,forEach,1,bool,$false,bool,$true
  415. else %Call = ,forEach,1,bool,$false,bool,$false
  416. while (%X < $0) {
  417. inc %x
  418. %Log = %Log $+ $($ $+ %X, 2) $+ ,
  419. if (%X > 2) %Call = %Call $+ ,bstr, $+ $ $+ %X
  420. }
  421. jfm_log -I $left(%Log,-1) $+ $chr(41) $+ $iif($prop !== $null,. $+ $v1)
  422. if ($0 < 2) %Error = INVAID_PARAMETERS
  423. elseif ($1 == 0) %Error = INVALID_HANDLER
  424. elseif ($prop !== $null) && ($prop !== walk) && ($prop !== fuzzy) { %Error = INVALID_PROPERTY }
  425. elseif ($0 > 2) && ($prop == walk) { %Error = PARAMETERS_NOT_APPLICABLE }
  426. elseif (!$1) || ($1 == 0) || (!$regex($1,/^((?:[^?:*]+)|(?:JSON:[^?:*]+(?::\d+)))$/)) { %Error = NAME_INVALID }
  427. else {
  428. if (JSON:?* iswm $1) %JSON = $com($1)
  429. elseif ($regex($1,/^\d+$/i)) {
  430. %X = 1
  431. %JSON = 0
  432. while ($com(%X)) {
  433. if ($regex($1,/^JSON:[^?*:]+$/)) {
  434. inc %JSON
  435. if (%JSON == $1) {
  436. %JSON = $com(%X)
  437. break
  438. }
  439. elseif (%X == $com(0)) %JSON = $null
  440. }
  441. inc %X
  442. }
  443. }
  444. else %JSON = $com(JSON: $+ $1)
  445. if (!%JSON) %Error = HANDLE_NOT_FOUND
  446. else {
  447. %Com = $gettok(%JSON,1-2,58) $+ :
  448. %X = $ticks $+ 000000
  449. while ($com(%Com $+ %X)) inc %x
  450. %Com = %Com $+ %X
  451. %Call = $!com( $+ %JSON $+ %Call $+ ,dispatch* %Com $+ )
  452. jfm_log %Call
  453. if (!$(%Call, 2)) || ($comerr) || (!$com(%Com)) { %Error = $jfm_GetError }
  454. else {
  455. .timer $+ %Com -iom 1 0 JSONClose $unsafe(%Com)
  456. if (!$com(%Com, length, 2)) || ($comerr) { %Error = $jfm_GetError }
  457. elseif ($com(%Com).result) {
  458. %Result = $v1
  459. %X = 0
  460. %ChildCom = $gettok(%Com,1-2,58) $+ :
  461. %Name = $ticks
  462. while ($com(%ChildCom $+ %Name)) inc %Name
  463. %Name = %ChildCom $+ %Name
  464. hinc -m SReject/JSONForMirc ForEach/Index
  465. hadd -m SReject/JSONForMirc ForEach/ $+ $hget(SReject/JSONForMirc,ForEach/Index) %Name
  466. while (%X < %Result) {
  467. if (!$com(%Com,%X,2,dispatch* %Name) || $comerr) {
  468. %Error = $jfm_GetError
  469. break
  470. }
  471. jfm_log -I Calling $1 %Name
  472. $2 %Name
  473. .comclose %Name
  474. jfm_log -D
  475. inc %X
  476. }
  477. hdel SReject/JSONForMirc ForEach/ $+ $hget(SReject/JSONForMirc, ForEach/Index)
  478. hdec SReject/JSONForMirc ForEach/Index
  479. if ($hget(SReject/JSONForMirc, ForEach/Index) == 0) hdel SReject/JsonForMirc ForEach/Index
  480. }
  481. }
  482. }
  483. }
  484. :error
  485. if ($error) %Error = $error
  486. reseterror
  487. if (%Error) {
  488. if ($com(%Com)) .comclose $v1
  489. if (JSON:* iswm %Name && $com(%Name)) { .comclose %Name }
  490. hadd -mu0 SReject/JSONForMirc Error %Error
  491. jfm_log -EeDF %Error
  492. }
  493. else {
  494. jfm_log -EsDF %Result
  495. return %Result
  496. }
  497. }
  498. alias JSONItem {
  499. var %Com = $hget(SReject/JSONForMirc,ForEach/ $+ $hget(SReject/JSONForMirc,ForEach/Index)),%Type,%Bvar,%Text
  500. if (!$isid || !%Com || !$com(%Com)) { return }
  501. if ($1 == Value || $1 == Valuetobvar) {
  502. %BVar = $jfm_TmpBVar
  503. noop $com(%Com, value, 1) $Com(%Com, %BVar).result
  504. if ($1 == valuetobvar) return %Bvar
  505. %Text = $bvar(%BVar, 1, 4000).text
  506. bunset %BVar
  507. return %Text
  508. }
  509. elseif ($1 == Length) {
  510. noop $com(%com, length, 1)
  511. return $com(%com).result
  512. }
  513. elseif ($1 == Type || $1 == IsContainer) {
  514. noop $com(%Com, type, 1)
  515. %type = $com(%Com).result
  516. if ($1 == type) return %Type
  517. if (%type == Object || %Type == Array) { return $true }
  518. return $false
  519. }
  520. }
  521. alias JSONPath {
  522. if (!$isid) return
  523. if ($hget(SReject/JSONForMirc,Error)) hdel SReject/JSONForMirc Error
  524. var %Error,%Param,%X 0,%JSON,%Result
  525. while (%X < $0) {
  526. inc %X
  527. %Param = %Param $+ $($ $+ %X,2) $+ ,
  528. }
  529. jfm_log -I $!JSONPath( $+ $left(%Param,-1) $+ )
  530. if ($0 !== 2) %Error = INVALID_PARAMETERS
  531. elseif ($prop !== $null) %Error = PROP_NOT_APPLICABLE
  532. elseif (!$1) || ($1 == 0) || (!$regex($1, /^(?:(?:JSON:[^?:*]+(?::\d+)*)?|([^?:*]+))$/i)) { %Error = NAME_INVALID }
  533. elseif ($2 !isnum 0-) || (. isin $2) { %Error = INVALID_INDEX }
  534. else {
  535. %JSON = $JSON($1)
  536. if ($JSONError) %Error = $v1
  537. elseif (!%JSON) %Error = HANDLER_NOT_FOUND
  538. elseif ($JSON(%JSON).pathLength == $null) %Error = $JSONError
  539. else {
  540. %Result = $v1
  541. if (!$2) noop
  542. elseif ($2 > %Result) unset %Result
  543. elseif (!$com(%JSON, pathAtIndex, 1, bstr, $calc($2 -1))) || ($comerr) { %Error = $jfm_GetError }
  544. else %Result = $com(%JSON).result
  545. }
  546. }
  547. :error
  548. if ($error) %Error = $v1
  549. reseterror
  550. if (%Error) {
  551. hadd -mu0 SReject/JSONForMirc Error %Error
  552. jfm_log -EeDF %Error
  553. }
  554. else {
  555. jfm_log -EsDF %Result
  556. return %Result
  557. }
  558. }
  559. alias JSONError if ($isid) return $hget(SReject/JSONForMirc,Error)
  560. alias JSONVersion {
  561. if ($isid) {
  562. var %Ver 1.0.4000
  563. if ($0) return %Ver
  564. return SReject/JSONForMirc v $+ %Ver
  565. }
  566. }
  567. alias JSONDebug {
  568. var %State $false, %aline aline $color(info2) @SReject/JSONForMirc/Log
  569. if ($group(#SReject/JSONForMirc/Log) == on) {
  570. if (!$window(@SReject/JSONForMirc/Log)) .disable #SReject/JSONForMirc/log
  571. else %State = $true
  572. }
  573. if ($isid) return %State
  574. elseif (!$0) || ($1 == toggle) {
  575. if (%State) tokenize 32 disable
  576. else tokenize 32 enable
  577. }
  578. if ($1 == on) || ($1 == enable) {
  579. if (%State) {
  580. echo $color(info).dd -atngq * /JSONDebug: debug already enabled
  581. return
  582. }
  583. .enable #SReject/JSONForMirc/Log
  584. %State = $true
  585. }
  586. elseif ($1 == off) || ($1 == disable) {
  587. if (!%State) {
  588. echo $color(info).dd -atngq * /JSONDebug: debug already disabled
  589. return
  590. }
  591. .disable #SReject/JSONForMirc/Log
  592. %State = $false
  593. }
  594. else {
  595. echo $color(info).dd -atng * /JSONDebug: Unknown input
  596. return
  597. }
  598. if (%State) {
  599. if (!$window(@SReject/JSONForMirc/Log)) window -zk0ej10000 @SReject/JSONForMirc/Log
  600. %aline Debug now enabled
  601. if ($~adiircexe) %aline AdiIRC v $+ $version $iif($beta, beta $builddate) $bits $+ bit
  602. else %aline mIRC v $+ $version $iif($beta, beta $v1) $bits $+ bit
  603. %aline $JSONVersion $iif($JSONCompat, [CompatMode], [NormalMode])
  604. %aline -
  605. }
  606. elseif ($Window(@SReject/JSONForMirc/Log)) %aline [JSONDebug] Debug now disabled
  607. window -b @SReject/JSONForMirc/Log
  608. }
  609. alias -l jfm_TmpBVar {
  610. var %N $ticks $+ 00000
  611. jfm_log -I $!jfm_TmpBVar
  612. while ($bvar(&SReject/JSONForMirc/Tmp $+ %N)) inc %N
  613. jfm_log -EsD &SReject/JSONForMirc/Tmp $+ %N
  614. return &SReject/JSONForMirc/Tmp $+ %N
  615. }
  616. alias -l jfm_ComInit {
  617. var %Error,%Js $jfm_tmpbvar
  618. jfm_log -I $!jfm_ComInit
  619. if ($com(SReject/JSONForMirc/JSONShell) && $com(SReject/JSONForMirc/JSONEngine)) {
  620. jfm_log -EsD Already Initialized
  621. return
  622. }
  623. jfm_jscript %Js
  624. if ($com(SReject/JSONForMirc/JSONEngine)) .comclose $v1
  625. if ($com(SReject/JSONForMirc/JSONShell)) .comclose $v1
  626. if ($~adiircexe !== $null) && ($bits == 64) { .comopen SReject/JSONForMirc/JSONShell ScriptControl }
  627. else .comopen SReject/JSONForMirc/JSONShell MSScriptControl.ScriptControl
  628. if (!$com(SReject/JSONForMirc/JSONShell)) || ($comerr) { %Error = SCRIPTCONTROL_INIT_FAIL }
  629. elseif (!$com(SReject/JSONForMirc/JSONShell, language, 4, bstr, jscript)) || ($comerr) { %Error = LANGUAGE_SET_FAIL }
  630. elseif (!$com(SReject/JSONForMirc/JSONShell, AllowUI, 4, bool, $false)) || ($comerr) { %Error = ALLOWIU_SET_FAIL }
  631. elseif (!$com(SReject/JSONForMirc/JSONShell, timeout, 4, integer, -1)) || ($comerr) { %Error = TIMEOUT_SET_FAIL }
  632. elseif (!$com(SReject/JSONForMirc/JSONShell, ExecuteStatement, 1, &bstr, %Js)) || ($comerr) { %Error = JSCRIPT_EXEC_FAIL }
  633. elseif (!$com(SReject/JSONForMirc/JSONShell, Eval, 1, bstr, this, dispatch* SReject/JSONForMirc/JSONEngine)) || ($comerr) || (!$com(SReject/JSONForMirc/JSONEngine)) { %Error = ENGINE_GET_FAIL }
  634. :error
  635. if ($error) {
  636. %Error = $v1
  637. reseterror
  638. }
  639. if (%Error) {
  640. if ($com(SReject/JSONForMirc/JSONEngine)) .comclose $v1
  641. if ($com(SReject/JSONForMirc/JSONShell)) .comclose $v1
  642. jfm_log -EeD %Error
  643. return %Error
  644. }
  645. else jfm_log -EsD Successfully initialized
  646. }
  647. alias -l jfm_ToggleTimers {
  648. var %x 1,%timer
  649. while ($timer(%x)) {
  650. %timer = $v1
  651. if ($regex(%timer,/^JSON:[^\?\*\:]+$/i)) $+(.timer,%timer) $1
  652. inc %x
  653. }
  654. }
  655. alias -l jfm_GetError {
  656. var %Error = UNKNOWN
  657. jfm_log -I $!jfm_GetError
  658. if ($com(SReject/JSONForMirc/JSONShell).errortext) %Error = $v1
  659. if ($com(SReject/JSONForMirc/JSONShellError)) .comclose SReject/JSONForMirc/JSONShellError
  660. if ($com(SReject/JSONForMirc/JSONShell,Error,2,dispatch* SReject/JSONForMirc/JSONShellError)) && (!$comerr) && ($com(SReject/JSONForMirc/JSONShellError)) && ($com(SReject/JSONForMirc/JSONShellError,Description,2)) && (!$comerr) && ($com(SReject/JSONForMirc/JSONShellError).result !== $null) { %Error = $v1 }
  661. if ($com(SReject/JSONForMirc/JSONShellError)) .comclose SReject/JSONForMirc/JSONShellError
  662. jfm_log -EsD %Error
  663. return %Error
  664. }
  665. alias -l jfm_Create {
  666. var %Wait $iif(1 & $4,$true,$false),%Parse $iif(2 & $4,$false,$true),%Error
  667. jfm_log -I $!jfm_create( $+ $1 $+ , $+ $2 $+ , $+ $3 $+ , $+ $4 $+ , $+ $5 $+ )
  668. if (!$com(SReject/JSONForMirc/JSONEngine,JSONCreate,1,bstr,$2,&bstr,$3,bool,%Parse,dispatch* $1)) || ($comerr) || (!$com($1)) { %Error = $jfm_GetError }
  669. elseif ($2 !== http) || ($2 == http && !%Wait) { %Error = $jfm_Exec($1,parse) }
  670. if (%Error) {
  671. jfm_log -EeD %Error
  672. return %Error
  673. }
  674. jfm_log -EsD Created $1
  675. }
  676. alias -l jfm_Exec {
  677. var %Args,%Index 0,%Params,%Error
  678. if ($hget(SReject/JSONForMirc,Exec)) hdel SReject/JSONForMirc Exec
  679. while (%Index < $0) {
  680. inc %Index
  681. %Args = %Args $+ $iif($len(%Args),$chr(44)) $+ $($ $+ %Index,2)
  682. if (%Index >= 3) {
  683. if ($prop == fromBvar) && ($regex($($ $+ %Index,2),/^& (&\S+)$/)) { %Params = %Params $+ ,&bstr, $+ $regml(1) }
  684. else %Params = %Params $+ ,bstr,$ $+ %Index
  685. }
  686. }
  687. %Params = $!com($1,$2,1 $+ %Params $+ )
  688. jfm_log -I $!jfm_Exec( $+ %Args $+ )
  689. if (!$(%Params,2) || $comerr) {
  690. %Error = $jfm_GetError
  691. jfm_log -EeD %Error
  692. return %Error
  693. }
  694. else {
  695. hadd -mu0 SReject/JSONForMirc Exec $jfm_tmpbvar
  696. noop $com($1, $hget(SReject/JSONForMirc, Exec)).result
  697. jfm_log -EsD Result stored in $hget(SReject/JSONForMirc,Exec)
  698. }
  699. }
  700. #SReject/JSONForMirc/Log off
  701. alias -l jfm_log {
  702. var %Switches,%Prefix ->,%Color 03,%Indent
  703. if (!$window(@SReject/JSONForMirc/Log)) {
  704. .JSONDebug off
  705. if ($hget(SReject/JSONForMirc,LogIndent)) hdel SReject/JSONForMirc LogIndent
  706. }
  707. else {
  708. if (-?* iswm $1) {
  709. %Switches = $mid($1, 2-)
  710. tokenize 32 $2-
  711. }
  712. if (i isincs %Switches) hinc -mu1 SReject/JSONForMirc LogIndent
  713. if ($0) {
  714. if (E isincs %Switches) %Prefix = <-
  715. if (e isincs %Switches) %Color = 04
  716. elseif (s isincs %Switches) %Color = 12
  717. elseif (l isincs %Switches) %Color = 13
  718. %Prefix = $chr(3) $+ %Color $+ %Prefix
  719. if (F !isincs %Switches) %Prefix = %Prefix $+ $chr(15)
  720. %Indent = $str($chr(15) $+ $chr(32), $calc($hget(SReject/JSONForMirc, LogIndent) *4))
  721. echo -gi $+ $calc(($hget(SReject/JSONForMirc, LogIndent) + 1) * 4 -1) @SReject/JSONForMirc/Log %Indent %Prefix $1-
  722. }
  723. if (I isincs %Switches) hinc -mu1 SReject/JSONForMirc LogIndent 1
  724. if (D isincs %Switches) && ($hget(SReject/JSONForMirc, LogIndent) > 0) { hdec -mu1 SReject/JSONForMirc LogIndent 1 }
  725. }
  726. }
  727. #SReject/JSONForMirc/Log end
  728. alias -l jfm_log noop
  729. alias -l jfm_SaveDebug {
  730. if ($isid) {
  731. if ($window(@SReject/JSONForMirc/Log)) && ($line(@SReject/JSONForMirc/Log, 0)) { return $true }
  732. return $false
  733. }
  734. var %File $sfile($envvar(USERPROFILE) $+ \Documents\JSONForMirc.log, JSONForMirc - Debug window, Save)
  735. if (%File) && (!$isfile(%File) || $input(Are you sure you want to overwrite $nopath(%File) $+ ?, qysa, @SReject/JSONForMirc/Log, Overwrite)) { savebuf @SReject/JSONForMirc/Log $qt(%File) }
  736. }
  737. alias -l jfm_badd {
  738. bset -t $1 $calc(1 + $bvar($1, 0)) $2-
  739. }
  740. alias -l jfm_jscript {
  741. jfm_badd $1 !function(){Array.prototype.forEach=function(c){for(var s=this,i=0;i<s.length;i++)c.call(s,s[i],i)};Array.prototype.find=function(c){for(var s=this,i=0;i<s.length;i+=1)if(c.call(s,s[i]))return s[i]};I=['MSXML2.SERVERXMLHTTP.6.0','MSXML2.SERVERXMLHTTP.3.0','MSXML2.SERVERXMLHTTP'].find(function(x){try{return new ActiveXObject(x),x}catch(e){}});function A(o){if(o===null)return 'null';return Object.prototype.toString.call(o).match(/^\[object ([^\]]+)\]$/)[1].toLowerCase()}function B(o){var k=[],i;for(i in o)if(C(o,i))k.push(i);return k}
  742. jfm_badd $1 function C(o,k){return Object.prototype.hasOwnProperty.call(o,k)}
  743. jfm_badd $1 function D(s){if(s._state!=='done'||s._error||!s._parse)throw new Error('NOT_D');return s}
  744. jfm_badd $1 function E(s){if(s._type!=='http')throw new Error('HTTP_NOT_INUSE');if(s._state!=='http_pending')throw new Error('HTTP_NOT_PENDING');return s._http}
  745. jfm_badd $1 function F(s){if(s._type!=='http')throw new Error('HTTP_NOT_INUSE');if(s._state!=='done')throw new Error('HTTP_PENDING');return s._http}
  746. jfm_badd $1 function G(v){var t=A(v),r='[';if(v===undefined||t==='function')return;if(v===null)return'null';if(t==='number')return isFinite(v)?v.toString():'null';if(t==='boolean')return v.toString();if(t==='string')return'"'+v.replace(/[\\"\u0000-\u001F\u2028\u2029]/g,function(c){return{'"':'\\"','\\':'\\\\','\b':'\\b','\f':'\\f','
  747. ':'\
  748. ','
  749. ':'\
  750. ','\t':'\\t'}[c]||'\\u'+(c.charCodeAt(0)+0x10000).toString(16).substr(1)})+'"';if(t==='array'){v.forEach(function(i,k){i=G(i);if(i)r+=(k?',':'')+i});return r+']'}r=[];B(v).forEach(function(k,o){o=G(v[k]);if(o)r.push(G(k)+':'+o)});return'{'+r.join(',')+'}'}
  751. jfm_badd $1 function H(p,j,s){s=this;if(p===undefined)p={};if(j===undefined){s._isChild=!1;s._json=p._json||{}}else{s._isChild=!0;s._json=j}s._state=p._state||'init';s._type=p._type||'text';s._parse=p._parse===!1?!1:!0;s._error=p._error||!1;s._input=p._input;s._http=p._http||{method:'GET',url:'',headers:[]}}
  752. jfm_badd $1 H.prototype={
  753. jfm_badd $1 state:function(){return this._state},
  754. jfm_badd $1 error:function(){return this._error.message},inputType:function(){return this._type},
  755. jfm_badd $1 input:function(){return this._input||null},
  756. jfm_badd $1 httpParse:function(){return this._parse},
  757. jfm_badd $1 httpSetMethod:function(m){E(this).method=m},
  758. jfm_badd $1 httpSetHeader:function(h,v){E(this).headers.push([h,v])},
  759. jfm_badd $1 httpSetData:function(d){E(this).data=d},
  760. jfm_badd $1 httpStatus:function(){return F(this).response.status},
  761. jfm_badd $1 httpStatusText:function(){return F(this).response.statusText},
  762. jfm_badd $1 httpHeaders:function(){return F(this).response.getAllResponseHeaders()},
  763. jfm_badd $1 httpHeader:function(h){return F(this).response.getResponseHeader(h)},
  764. jfm_badd $1 httpBody:function(){return F(this).response.responseBody},
  765. jfm_badd $1 httpHead:function (s){return s=this,s.httpStatus()+' '+s.httpStatusText()+'
  766. '+s.httpHeaders()},
  767. jfm_badd $1 httpResponse:function(){return this.httpHead()+'
  768.  
  769. '+this._http.response.reponseText},
  770. jfm_badd $1 parse:function(){var s=this,d=!0,x=!1,y=!1,r,j;s.parse=function(){throw new Error('PARSE_NOT_PENDING')};s._state='done';try{if(s._type==='http'){try{if(s._http.data==undefined){d=!1;s._http.data=null}r=new ActiveXObject(I);s._http.response=r;r.open(s._http.method,s._http.url,!1);s._http.headers.forEach(function(h){r.setRequestHeader(h[0],h[1]);if(h[0].toLowerCase()==="content-type")x=!0;if(h[0].toLowerCase()==="content-length")y=!0});if(d){if(!x)r.setRequestHeader("Content-Type","application/x-www-form-urlencoded");if(!y){if(s._http.data==null)r.setRequestHeader("Content-Length",0);else r.setRequestHeader("Content-Length",String(s._http.data).length)}}r.send(s._http.data);if(s._parse===!1)return s;s._input=r.responseText}catch(e){e.message="HTTP: "+e.message;throw e}}j=String(s._input).replace(/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,function(c){return'\\u'+('0000'+c.charCodeAt(0).toString(16)).slice(-4)});if(!/^[\],:{}\s]*$/.test(j.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\
  771.  
  772. ]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,'')))throw new Error("INVALID_JSON");try{j=eval('('+j+')')}catch(e){throw new Error("INVALID_JSON")}s._json={path:[],value:j};return s}catch(e){s._error=e.message;throw e}},
  773. jfm_badd $1 walk:function(){var s=D(this),r=s._json.value,a=Array.prototype.slice.call(arguments),f=a.shift(),p=s._json.path.slice(0),t,m,i,k;while(a.length){t=A(r);m=String(a.shift());if(t!=='array'&&t!=='object')throw new Error('ILLEGAL_REFERENCE');if(f&&/^[~=]./.test(m)){i='~'===m.charAt(0);m=m.replace(/^[~=]\x20?/,'');if(t=='object'&&i){k=B(r);if(/^\d+$/.test(m)){m=parseInt(m,10);if(m>=k.length)throw new Error('FUZZY_INDEX_NOT_FOUND');m=k[m]}else if(!C(r,m)){m=m.toLowerCase();m=k.find(function(k){return m===k.toLowerCase()});if(m==undefined)throw new Error('FUZZY_MEMBER_NOT_FOUND')}}}if(!C(r,m))throw new Error('REFERENCE_NOT_FOUND');p.push(m);r=r[m]}return new H(s,{path:p,value:r})},
  774. jfm_badd $1 forEach:function(){var s=D(this),a=Array.prototype.slice.call(arguments),r=[],d=a[0]?Infinity:1;a.shift();function _(i,p,j){j=new H(s,{path:p,value:i});if(d!==Infinity&&a.length>1)j=j.walk.apply(j,a.slice(0));r.push(j)}function Z(i,p,c,t){t=A(i);p=p.slice(0);if(c>d)_(i,p);else if(t==='object')B(i).forEach(function(k,z){z=p.slice(0);z.push(k);Z(i[k],z,c+1)});else if(t==='array')i.forEach(function(v,k){z=p.slice(0);z.push(k);Z(v,z,c+1)});else _(i,p)}if(s.type()!=='object'&&s.type()!=='array')throw new Error('ILLEGAL_REFERENCE');Z(s._json.value,s._json.path.slice(0),1);return r},
  775. jfm_badd $1 type:function(){return A(D(this)._json.value)},
  776. jfm_badd $1 isContainer:function(){return(this.type()==="object"||this.type()==="array")},
  777. jfm_badd $1 pathLength:function(){return D(this)._json.path.length},
  778. jfm_badd $1 pathAtIndex:function(i){return D(this)._json.path[i]},
  779. jfm_badd $1 path:function(){var r='';D(this)._json.path.forEach(function(i){r+=(r?' ':'')+String(i).replace(/([\\ ])/g,function(c){return' '=== c?'\s':'\\'})});return r},
  780. jfm_badd $1 length:function(){var s=D(this),t=s.type();if(t==='string'||t==='array')return s._json.value.length;if(t==='object')return B(s._json.value).length;throw new Error('INVALID_TYPE')},
  781. jfm_badd $1 value:function(){return D(this)._json.value},
  782. jfm_badd $1 string:function(){return G(D(this)._json.value)},
  783. jfm_badd $1 debug:function(){var s=this,r={state:s._state,input:s._input,type:s._type,error:s._error,parse:s._parse,http:{url:s._http.url,method:s._http.method,headers:s._http.headers,data:s._http.data},isChild:s._isChild,json:s._json};if(s._type==="http"&&s._state==="done")r.http.response={status:s._http.response.status,statusText:s._http.response.statusText,headers:(s._http.response.getAllResponseHeaders()).split(/[
  784. ]+/g),responseText:s._http.response.responseText};return G(r)}};
  785. jfm_badd $1 JSONCreate=function(t,i,p,s){s=new H();s._state='init';s._type=(t||'text').toLowerCase();s._parse=p===!1?!1:!0;if(s._type==='http'){if(!I){s._error='HTTP_NOT_FOUND';throw new Error('HTTP_NOT_FOUND')}s._state='http_pending';s._http.url=i}else{s._state='parse_pending';s._input=i}return s}}()
  786. }
  787.  


Comments (1)
June 11th, 2018 - By: westor
Admin
It is recommented to click on " ownload" button instead of copy/paste the Source Code.

Login to Comment.