├── .project ├── README.md ├── api ├── mtgox0.js └── mtgox1.js ├── background.js ├── chart.html ├── css ├── jquery-ui-1.8.20.css ├── jquery.jqChart.css ├── jquery.jqRangeSlider.css └── table.css ├── icon.gif ├── icon_128.gif ├── img ├── chart.png └── options.png ├── js ├── chart.js ├── excanvas.js ├── jquery-1.7.2.min.js ├── jquery.jqChart.min.js └── jquery.jqRangeSlider.min.js ├── manifest.json ├── options.html ├── options.js ├── popup.html ├── popup.js └── sha512.js /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | GoxTradingBot 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | GoxTradingBot 2 | ============= 3 | 4 | Gox Trading Bot Chrome Extension 5 | 6 | 7 | 8 | 9 | This work is based on: 10 | 11 | - Gox Trading Bot (https://chrome.google.com/webstore/detail/gox-trading-bot/iejmifigokhpcgpmoacllcdiceicmejb) 12 | - Discussion thread (https://bitcointalk.org/index.php?topic=67591.0) 13 | - Base idea (https://bitcointalk.org/index.php?topic=60501) 14 | 15 | **The code was provided for educational/fun purposes and shouldn't be used to trade significant amounts of BTC!** 16 | 17 | Neither original author nor modifiers of the code are to be responsible for any damage caused by using this bot. 18 | There is no warranty of any kind that the source will perform according to any specification/expectations. 19 | 20 | **You as user are fully responsible for analysing the code and deciding if and how to use it.** 21 | 22 | 23 | Configuration: 24 | --- 25 | 26 | Constants in file background.js: 27 | 28 | **MaxHoursToKeep** - how many bars are kept in history to calculate EMA trends 29 | 30 | **btcPreserve** - amount of BTC that shouldn't be touched by trade (all amount above that will be used) 31 | 32 | **btcFiat** - replace with Your currency 33 | 34 | **bidWithLastPrice** - bid with last price rather than market price (poorly tested - for now effects in "dead" orders) 35 | 36 | 37 | Options to configure in run time: 38 | 39 | **MtGox API Key** - API key from MtGox 40 | 41 | **MtGox API Secret** - API secret from MtGox 42 | 43 | **EMAShort/EMALong** - EMA tick lengths 44 | 45 | **sellTreshold/buyTreshold** - sell/buy thresholds 46 | 47 | **Show last x days** - how many days of history to present 48 | 49 | **Enable Trading** - switch between trade and simulation mode 50 | 51 | **EMA Timeframe** - interval between ticks 52 | 53 | **Last Buy to Sell trigger** - difference in price to keep when selling BTC (comparing to wallet history) 54 | 55 | **Last Sell to Buy trigger** - same as above when buying BTC ("sold price" to "bought price" relation,"0" means no difference keeping) 56 | 57 | 58 | 59 | Installation: 60 | --- 61 | 62 | 1. Copy files from github to Your local storage. 63 | 2. Configure background.js according to above specs 64 | 3. Run Chrome and goto "chrome://extensions/" url 65 | 4. Click on (developer mode) "Read extension without package" and choose Your local folder 66 | 67 | 68 | Changes: 69 | --- 70 | 71 | 0.2.0.2 72 | - added chart with trends (a link from popup near balance) 73 | - added **hrInterval** 74 | - option to bid with last price rather than market price () 75 | - different thresholds buy/sell 76 | - other minor fixes 77 | 78 | 0.2.0.3 79 | - hrInterval moved to dynamic (UI) options 80 | - "enableTrade" flag 81 | - minor layout fixes 82 | 83 | 0.2.0.4 84 | - added history data, gui fixes 85 | 86 | 0.2.0.5 87 | - added balance check using v1 api 88 | - added buy/sell difference keeper 89 | - other minor fixes 90 | 91 | Wanna feature? Donations: 92 | --- 93 | BTC:13eJdr8ndc3MJAeHGpVTNMPUtTGE8ANHpL 94 | -------------------------------------------------------------------------------- /api/mtgox0.js: -------------------------------------------------------------------------------- 1 | 2 | function update() { 3 | mtgoxpost("info.php", [], 4 | function(e) { 5 | console.log("info error", e) 6 | chrome.browserAction.setTitle({title: "Error executing info" }); 7 | schedupdate(10*1000) // retry after 10 seconds 8 | }, 9 | function(d) { 10 | console.log("info.php", d.currentTarget.responseText) 11 | BTC = Number.NaN 12 | USD = Number.NaN 13 | try { 14 | var rr = JSON.parse(d.currentTarget.responseText) 15 | if (typeof(rr.Wallets[btcFiat].Balance.value)=="undefined") { 16 | chrome.browserAction.setTitle({title: rr.error }); 17 | } else { 18 | BTC = parseFloat(rr.Wallets.BTC.Balance.value) 19 | USD = parseFloat(rr.Wallets[btcFiat].Balance.value) 20 | chrome.browserAction.setTitle({title: (rr.Wallets.BTC.Balance.value + " BTC + " + rr.Wallets[btcFiat].Balance.value + " " + btcFiat) }); 21 | } 22 | } catch (e) { 23 | console.log(e) 24 | chrome.browserAction.setTitle({title: e.toString() }); 25 | } 26 | schedupdate(5*60*1000) // Update balance every 5 minutes 27 | } 28 | ) 29 | } -------------------------------------------------------------------------------- /api/mtgox1.js: -------------------------------------------------------------------------------- 1 | 2 | function update() { 3 | mtgoxpost1("generic/private/info", [], 4 | function(e) { 5 | console.log("info error", e) 6 | chrome.browserAction.setTitle({title: "Error executing info" }); 7 | schedupdate(10*1000) // retry after 10 seconds 8 | }, 9 | function(d) { 10 | console.log("generic/private/info", d.currentTarget.responseText) 11 | BTC = Number.NaN 12 | USD = Number.NaN 13 | try { 14 | var rr = JSON.parse(d.currentTarget.responseText) 15 | if (rr.result == 'success') { 16 | rr = rr.return; 17 | if (typeof(rr.Wallets[btcFiat].Balance.value)=="undefined") { 18 | chrome.browserAction.setTitle({title: rr.error }); 19 | } else { 20 | BTC = parseFloat(rr.Wallets.BTC.Balance.value) 21 | USD = parseFloat(rr.Wallets[btcFiat].Balance.value) 22 | chrome.browserAction.setTitle({title: (rr.Wallets.BTC.Balance.value + " BTC + " + rr.Wallets[btcFiat].Balance.value + " " + btcFiat) }); 23 | } 24 | } else { 25 | console.log("info soft error", rr.error) 26 | chrome.browserAction.setTitle({title: "Error executing info:"+rr.error }); 27 | //schedupdate(100*1000) // retry after 100 seconds 28 | } 29 | } catch (e) { 30 | console.log(e) 31 | chrome.browserAction.setTitle({title: e.toString() }); 32 | } 33 | schedupdate(5*60*1000) // Update balance every 5 minutes 34 | } 35 | ) 36 | } -------------------------------------------------------------------------------- /background.js: -------------------------------------------------------------------------------- 1 | const MaxHoursToKeep = 144; 2 | const btcPreserve = 5; // this amount will be untouched by trade - bot will play with the rest 3 | const btcFiat = 'USD'; // change this to Your currency 4 | // const TimeFrame = 1800;// interval as number of seconds (ie 3600 - 1 hour) 5 | const bidWithLastPrice = false; // use last price to bid rather than market one 6 | 7 | var ApiKey = localStorage.ApiKey || ''; 8 | var ApiSec = localStorage.ApiSec || ''; 9 | 10 | var tradingEnabled = (localStorage.tradingEnabled || 1); 11 | var bsTrigSell = (localStorage.bsTrigSell || 0); 12 | var bsTrigBuy = (localStorage.bsTrigBuy || 0); 13 | 14 | var EmaShortPar = parseInt(localStorage.EmaShortPar || 10); 15 | var EmaLongPar = parseInt(localStorage.EmaLongPar || 21); 16 | var MaxHoursBack = parseInt(localStorage.MaxHoursBack || MaxHoursToKeep); 17 | var MinThresholdBuy = parseFloat(localStorage.MinThresholdBuy || 0.25); 18 | var MinThresholdSell = parseFloat(localStorage.MinThresholdSell || 0.25); 19 | var LogLines = parseInt(localStorage.LogLines || 12); 20 | var TimeFrame = parseInt(localStorage.TimeFrame || 3600); 21 | 22 | var BTC, USD; 23 | var utimer=null; 24 | var bootstrap = 1; // progress bar for loading initial H1 data from mtgox 25 | 26 | var H1 = []; // the H1 data 27 | var tim = []; 28 | var emaLong = []; 29 | var emaShort = []; 30 | 31 | var popupRefresh=null; 32 | var popupUpdateCounter=null; 33 | var updateinprogress=false; 34 | 35 | 36 | function updateEMA(ema, N) { 37 | var pr, k = 2 / (N+1); 38 | while (ema.length < H1.length) { 39 | if (ema.length==0) { 40 | ema.push(H1[0]); 41 | } else { 42 | ema.push( H1[ema.length] * k + ema[ema.length-1] * (1-k) ) 43 | } 44 | } 45 | } 46 | 47 | function schedupdate(t) { 48 | if (utimer) clearTimeout() 49 | utimer = setTimeout(update,t) 50 | } 51 | 52 | 53 | function signdata(data) { 54 | var shaObj = new jsSHA(data, "ASCII") 55 | var SecretKey = atob(ApiSec) 56 | var hmac = shaObj.getHMAC(SecretKey, "ASCII", "SHA-512", "B64") 57 | while (hmac.length%4) hmac+='=' // workaround for the B64 too short bug 58 | return hmac 59 | } 60 | 61 | 62 | function mtgoxpost(page, params, ef, df) { 63 | var req = new XMLHttpRequest() 64 | req.open("POST", "https://mtgox.com/api/0/"+page, true) 65 | req.onerror = ef 66 | req.onload = df 67 | var data = "nonce="+((new Date()).getTime()*1000) 68 | for (var i in params) data += "&" + params[i] 69 | data = encodeURI(data) 70 | var hmac = signdata(data) 71 | req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") 72 | req.setRequestHeader("Rest-Key", ApiKey) 73 | req.setRequestHeader("Rest-Sign", hmac) 74 | req.send(data) 75 | } 76 | 77 | function mtgoxpost1(page, params, ef, df) { 78 | var req = new XMLHttpRequest() 79 | req.open("POST", "https://mtgox.com/api/1/"+page, true) 80 | req.onerror = ef 81 | req.onload = df 82 | var data = "nonce="+((new Date()).getTime()*1000) 83 | for (var i in params) data += "&" + params[i] 84 | data = encodeURI(data) 85 | var hmac = signdata(data) 86 | req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") 87 | req.setRequestHeader("Rest-Key", ApiKey) 88 | req.setRequestHeader("Rest-Sign", hmac) 89 | req.send(data) 90 | } 91 | 92 | 93 | function hmac_512(message) { 94 | var secret = atob(ApiSec); 95 | var shaObj = new jsSHA(message, "TEXT"); 96 | var hmac = shaObj.getHMAC(secret, "B64", "SHA-512", "B64"); 97 | return hmac 98 | } 99 | 100 | function mtgoxpost2(page, params, ef, df) { 101 | var req = new XMLHttpRequest() 102 | req.open("POST", "https://mtgox.com/api/2/"+page, true) 103 | req.onerror = ef 104 | req.onload = df 105 | var data = 'nonce='+((new Date()).getTime()*1000); 106 | for (var i in params) data += "&" + params[i]; 107 | data = encodeURI(data); 108 | data = page + '\x00' + data; 109 | var hmac = hmac_512(data) 110 | //var hmac = signdata(data) 111 | req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") 112 | req.setRequestHeader("Rest-Key", ApiKey) 113 | req.setRequestHeader("Rest-Sign", hmac) 114 | req.send(data) 115 | } 116 | 117 | 118 | function one(e) { 119 | console.log("ajax post error", e) 120 | } 121 | 122 | function onl(d) { 123 | console.log("ajax post ok", d) 124 | schedupdate(2500) 125 | } 126 | 127 | 128 | function dat2day(ms) { 129 | var t = new Date(ms) 130 | var y = t.getUTCFullYear().toString() 131 | var m = (t.getUTCMonth()+1).toString() 132 | var d = t.getUTCDate().toString() 133 | if (m.length<2) m='0'+m; 134 | if (d.length<2) d='0'+d; 135 | return y+"-"+m+"-"+d 136 | } 137 | 138 | function get_url(req, url) { 139 | //console.log(url) 140 | req.open("GET", url) 141 | req.send(null); 142 | } 143 | 144 | 145 | function getemadif(idx) { 146 | var cel = emaLong[idx] 147 | var ces = emaShort[idx] 148 | return 100 * (ces-cel) / ((ces+cel)/2) 149 | } 150 | 151 | function extractPrice(sfrom){ 152 | var n=sfrom.indexOf("BTC at"); 153 | n+=6; 154 | var ret = -1; 155 | var s2 = sfrom.substr(n); 156 | var s3 = ""; 157 | for (var i=0; i='0') && (s2.charAt(i)<='9')) || (s2.charAt(i)=='.')){ 159 | s3 = s3 + s2.charAt(i); 160 | } 161 | } 162 | ret = parseFloat(s3); 163 | return ret; 164 | } 165 | 166 | function getWalletHistory(fonret,fonerr){ 167 | 168 | //var inf = ["nonce="+((new Date()).getTime()*1000),'currency=BTC',"nonce="+((new Date()).getTime()*1000)];//['since='+btcFiat,'amount=1000']; 169 | var inf = ['currency=BTC'];//['since='+btcFiat,'amount=1000']; 170 | //if (bidWithLastPrice) inf.push('price='+H1[H1.length-1].toString()); 171 | 172 | mtgoxpost1("generic/wallet/history", inf, 173 | function one(e) { 174 | console.log("ajax post error", e) 175 | if (fonerr!=null) fonerr(e); 176 | }, 177 | function onl(d) { 178 | console.log("ajax post ok", d); 179 | var rdo = JSON.parse(d.srcElement.responseText); 180 | if (rdo.result == "success") { 181 | fonret(rdo); 182 | } 183 | else { 184 | console.log("ERROR geting wallet history"); 185 | } 186 | //schedupdate(2500); 187 | } 188 | ); 189 | 190 | 191 | } 192 | 193 | function checkIfToTrade(stype,func){ 194 | 195 | var bInProgress =true; 196 | getWalletHistory(function(rdo){ 197 | 198 | var recNum = parseInt(rdo.return.records); 199 | for (var i=0; i0) 207 | if (((currPrice-prevPrice)*k/prevPrice) > (bsTrig/100)) {//trigger trade 208 | func(); 209 | } 210 | i=recNum;//end of loop 211 | } 212 | } 213 | bInProgress = false; 214 | }, 215 | function(e){ 216 | bInProgress = false; 217 | } 218 | ); 219 | 220 | } 221 | 222 | function checkIfToBuy(dif,func){ 223 | var bBuy = false; 224 | if (USD>=0.01) { 225 | if (getemadif(H1.length-1) > MinThresholdBuy) { 226 | if (tradingEnabled==1) { 227 | bBuy = true; 228 | } else { 229 | console.log("BUY switched off! (EMA("+EmaShortPar+")/EMA("+EmaLongPar+")>"+MinThresholdBuy+"%"); 230 | } 231 | } 232 | } else { 233 | console.log("No "+btcFiat+" to exec up-trend") 234 | } 235 | if (bBuy &&( bsTrigBuy>0)){// check yet history 236 | bBuy = false; 237 | checkIfToTrade("out",func); 238 | } 239 | 240 | return bBuy; 241 | } 242 | 243 | function checkIfToSell(dif,func){ 244 | var bSell = false; 245 | if (BTC>=btcPreserve) { 246 | var s = BTC - btcPreserve; 247 | if (getemadif(H1.length-1) < -MinThresholdSell) { 248 | if (tradingEnabled==1) { 249 | bSell = true; 250 | } else { 251 | console.log("SELL switched off! (EMA("+EmaShortPar+")/EMA("+EmaLongPar+")<-"+MinSellThreshold+"%"); 252 | } 253 | } 254 | } else { 255 | console.log("No BTC to exec down-trend") 256 | } 257 | if (bSell &&( bsTrigSell>0)){// check yet history 258 | bSell =false; 259 | checkIfToTrade("in",func); 260 | } 261 | 262 | return bSell; 263 | 264 | } 265 | 266 | 267 | function refreshEMA(reset) { 268 | if (reset) { 269 | emaLong = [] 270 | emaShort = [] 271 | } 272 | 273 | if (H1.length > MaxHoursToKeep) { 274 | var skip = H1.length-MaxHoursToKeep 275 | H1 = H1.slice(skip) 276 | tim = tim.slice(skip) 277 | emaLong = emaLong.slice(skip) 278 | emaShort = emaShort.slice(skip) 279 | } 280 | 281 | updateEMA(emaLong, EmaLongPar) 282 | updateEMA(emaShort, EmaShortPar) 283 | 284 | var dp, dif = getemadif(H1.length-1) 285 | chrome.browserAction.setBadgeText({text: Math.abs(dif).toFixed(2)}) 286 | 287 | if (dif>MinThresholdBuy) { 288 | chrome.browserAction.setBadgeBackgroundColor({color:[0, 128, 0, 200]}) 289 | if (checkIfToBuy(dif,function(){ 290 | if (tradingEnabled==1){ 291 | console.log("BUY!!!"); 292 | var inf = ['Currency='+btcFiat,'amount=1000']; 293 | if (bidWithLastPrice) inf.push('price='+H1[H1.length-1].toString()); 294 | mtgoxpost("buyBTC.php", inf, one, onl) 295 | } 296 | })) { 297 | 298 | } 299 | 300 | 301 | } else if (dif<-MinThresholdSell) { 302 | chrome.browserAction.setBadgeBackgroundColor({color:[128, 0, 0, 200]}) 303 | if (checkIfToSell(dif,function(){ 304 | if (tradingEnabled==1){ 305 | console.log("SELL!!!") 306 | var inf = ['Currency='+btcFiat,'amount='+s.toString()]; 307 | if (bidWithLastPrice) inf.push('price='+H1[H1.length-1].toString()); 308 | mtgoxpost("sellBTC.php", inf , one, onl) 309 | } 310 | })) { 311 | 312 | } 313 | 314 | } else { 315 | if (dif>0) { 316 | chrome.browserAction.setBadgeBackgroundColor({color:[10, 100, 10, 100]}) 317 | } else { 318 | chrome.browserAction.setBadgeBackgroundColor({color:[100, 10, 10, 100]}) 319 | } 320 | } 321 | 322 | } 323 | 324 | function updateH1() { 325 | if (updateinprogress) { 326 | return 327 | } 328 | updateinprogress = true 329 | 330 | var hour_fetch, hour_now = parseInt( (new Date()).getTime() / (TimeFrame*1000) ) 331 | if (tim.length>0) { 332 | hour_fetch = tim[tim.length-1] + 1 333 | if (hour_fetch > hour_now) { 334 | //console.log("Already have open price for the current hour") 335 | updateinprogress = false 336 | return 337 | } 338 | } else { 339 | hour_fetch = hour_now - MaxHoursBack 340 | } 341 | 342 | var req = new XMLHttpRequest() 343 | 344 | var url = "https://data.mtgox.com/api/0/data/getTrades.php?Currency="+btcFiat+"&since="+(hour_fetch*TimeFrame*1000000).toString() 345 | 346 | req.onerror = function(e) { 347 | console.log("getTrades error", e, "-repeat") 348 | get_url(req, url) 349 | } 350 | 351 | req.onload = function() { 352 | var refr = false 353 | var done = true 354 | try { 355 | //console.log(req.responseText) 356 | var trs = JSON.parse( req.responseText ) 357 | //console.log(trs.length) 358 | if (trs.length > 1) { 359 | tim.push(hour_fetch) 360 | var f = parseFloat(trs[0].price); 361 | var f0 = H1[H1.length-1]; 362 | if (((f/10)>=f0) || ((f*10)<=f0)){ // strange peaks elimination - just keep old val 363 | f=f0; 364 | } 365 | H1.push(f) 366 | hour_fetch++ 367 | if (hour_fetch <= hour_now) { 368 | url = "https://data.mtgox.com/api/0/data/getTrades.php?Currency="+btcFiat+"&since="+(hour_fetch*TimeFrame*1000000).toString() 369 | get_url(req, url) 370 | done = false 371 | if (bootstrap) { 372 | bootstrap++ 373 | chrome.browserAction.setBadgeText({text: (" | ").substr(bootstrap%9, 6)}) 374 | } 375 | } else { 376 | console.log("Got some new hours", H1.length, MaxHoursToKeep) 377 | refr = true 378 | bootstrap = 0 379 | } 380 | } 381 | } catch (e) { 382 | console.log("getTrades JSON error", e, req.responseText) 383 | chrome.browserAction.setBadgeText({text: "xxx"}) 384 | } 385 | if (refr) refreshEMA(false) 386 | if (done) updateinprogress = false 387 | if (refr && popupRefresh!=null) { 388 | try { 389 | popupRefresh() 390 | } catch (e) { 391 | popupRefresh=null 392 | } 393 | } else if (popupUpdateCounter!=null) { 394 | try { 395 | popupUpdateCounter(); 396 | } catch (e) { 397 | popupUpdateCounter=null; 398 | } 399 | } 400 | } 401 | get_url(req, url) 402 | } 403 | 404 | chrome.browserAction.setBadgeBackgroundColor({color:[128, 128, 128, 50]}) 405 | schedupdate(10) 406 | updateH1() 407 | setInterval(updateH1, 3*60*1000) // recheck every 3 minutes 408 | -------------------------------------------------------------------------------- /chart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Trends Chart 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 |
22 |
23 |
24 |

History:

25 | 26 | 28 |
29 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /css/jquery-ui-1.8.20.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI CSS Framework 1.8.20 3 | * 4 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 5 | * Dual licensed under the MIT or GPL Version 2 licenses. 6 | * http://jquery.org/license 7 | * 8 | * http://docs.jquery.com/UI/Theming/API 9 | */ 10 | 11 | /* Layout helpers 12 | ----------------------------------*/ 13 | .ui-helper-hidden { display: none; } 14 | .ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } 15 | .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } 16 | .ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } 17 | .ui-helper-clearfix:after { clear: both; } 18 | .ui-helper-clearfix { zoom: 1; } 19 | .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } 20 | 21 | 22 | /* Interaction Cues 23 | ----------------------------------*/ 24 | .ui-state-disabled { cursor: default !important; } 25 | 26 | 27 | /* Icons 28 | ----------------------------------*/ 29 | 30 | /* states and images */ 31 | .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } 32 | 33 | 34 | /* Misc visuals 35 | ----------------------------------*/ 36 | 37 | /* Overlays */ 38 | .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } 39 | 40 | 41 | /*! 42 | * jQuery UI CSS Framework 1.8.20 43 | * 44 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 45 | * Dual licensed under the MIT or GPL Version 2 licenses. 46 | * http://jquery.org/license 47 | * 48 | * http://docs.jquery.com/UI/Theming/API 49 | * 50 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=10px&bgColorHeader=3a8104&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=33&borderColorHeader=3f7506&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=285c00&bgTextureContent=05_inset_soft.png&bgImgOpacityContent=10&borderColorContent=72b42d&fcContent=ffffff&iconColorContent=72b42d&bgColorDefault=4ca20b&bgTextureDefault=03_highlight_soft.png&bgImgOpacityDefault=60&borderColorDefault=45930b&fcDefault=ffffff&iconColorDefault=ffffff&bgColorHover=4eb305&bgTextureHover=03_highlight_soft.png&bgImgOpacityHover=50&borderColorHover=8bd83b&fcHover=ffffff&iconColorHover=ffffff&bgColorActive=285c00&bgTextureActive=04_highlight_hard.png&bgImgOpacityActive=30&borderColorActive=72b42d&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=fbf5d0&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=f9dd34&fcHighlight=363636&iconColorHighlight=4eb305&bgColorError=ffdc2e&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=95&borderColorError=fad000&fcError=2b2b2b&iconColorError=cd0a0a&bgColorOverlay=444444&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=15&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=07_diagonals_small.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=0px&offsetTopShadow=4px&offsetLeftShadow=4px&cornerRadiusShadow=4px 51 | */ 52 | 53 | 54 | /* Component containers 55 | ----------------------------------*/ 56 | .ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; } 57 | .ui-widget .ui-widget { font-size: 1em; } 58 | .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; } 59 | .ui-widget-content { border: 1px solid #72b42d; background: #285c00 url(images/ui-bg_inset-soft_10_285c00_1x100.png) 50% bottom repeat-x; color: #ffffff; } 60 | .ui-widget-content a { color: #ffffff; } 61 | .ui-widget-header { border: 1px solid #3f7506; background: #3a8104 url(images/ui-bg_highlight-soft_33_3a8104_1x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } 62 | .ui-widget-header a { color: #ffffff; } 63 | 64 | /* Interaction states 65 | ----------------------------------*/ 66 | .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #45930b; background: #4ca20b url(images/ui-bg_highlight-soft_60_4ca20b_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; } 67 | .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #ffffff; text-decoration: none; } 68 | .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #8bd83b; background: #4eb305 url(images/ui-bg_highlight-soft_50_4eb305_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; } 69 | .ui-state-hover a, .ui-state-hover a:hover { color: #ffffff; text-decoration: none; } 70 | .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #72b42d; background: #285c00 url(images/ui-bg_highlight-hard_30_285c00_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; } 71 | .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff; text-decoration: none; } 72 | .ui-widget :active { outline: none; } 73 | 74 | /* Interaction Cues 75 | ----------------------------------*/ 76 | .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #f9dd34; background: #fbf5d0 url(images/ui-bg_glass_55_fbf5d0_1x400.png) 50% 50% repeat-x; color: #363636; } 77 | .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } 78 | .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #fad000; background: #ffdc2e url(images/ui-bg_diagonals-thick_95_ffdc2e_40x40.png) 50% 50% repeat; color: #2b2b2b; } 79 | .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #2b2b2b; } 80 | .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #2b2b2b; } 81 | .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } 82 | .ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } 83 | .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } 84 | 85 | /* Icons 86 | ----------------------------------*/ 87 | 88 | /* states and images */ 89 | .ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_72b42d_256x240.png); } 90 | .ui-widget-content .ui-icon {background-image: url(images/ui-icons_72b42d_256x240.png); } 91 | .ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } 92 | .ui-state-default .ui-icon { background-image: url(images/ui-icons_ffffff_256x240.png); } 93 | .ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } 94 | .ui-state-active .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } 95 | .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_4eb305_256x240.png); } 96 | .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } 97 | 98 | /* positioning */ 99 | .ui-icon-carat-1-n { background-position: 0 0; } 100 | .ui-icon-carat-1-ne { background-position: -16px 0; } 101 | .ui-icon-carat-1-e { background-position: -32px 0; } 102 | .ui-icon-carat-1-se { background-position: -48px 0; } 103 | .ui-icon-carat-1-s { background-position: -64px 0; } 104 | .ui-icon-carat-1-sw { background-position: -80px 0; } 105 | .ui-icon-carat-1-w { background-position: -96px 0; } 106 | .ui-icon-carat-1-nw { background-position: -112px 0; } 107 | .ui-icon-carat-2-n-s { background-position: -128px 0; } 108 | .ui-icon-carat-2-e-w { background-position: -144px 0; } 109 | .ui-icon-triangle-1-n { background-position: 0 -16px; } 110 | .ui-icon-triangle-1-ne { background-position: -16px -16px; } 111 | .ui-icon-triangle-1-e { background-position: -32px -16px; } 112 | .ui-icon-triangle-1-se { background-position: -48px -16px; } 113 | .ui-icon-triangle-1-s { background-position: -64px -16px; } 114 | .ui-icon-triangle-1-sw { background-position: -80px -16px; } 115 | .ui-icon-triangle-1-w { background-position: -96px -16px; } 116 | .ui-icon-triangle-1-nw { background-position: -112px -16px; } 117 | .ui-icon-triangle-2-n-s { background-position: -128px -16px; } 118 | .ui-icon-triangle-2-e-w { background-position: -144px -16px; } 119 | .ui-icon-arrow-1-n { background-position: 0 -32px; } 120 | .ui-icon-arrow-1-ne { background-position: -16px -32px; } 121 | .ui-icon-arrow-1-e { background-position: -32px -32px; } 122 | .ui-icon-arrow-1-se { background-position: -48px -32px; } 123 | .ui-icon-arrow-1-s { background-position: -64px -32px; } 124 | .ui-icon-arrow-1-sw { background-position: -80px -32px; } 125 | .ui-icon-arrow-1-w { background-position: -96px -32px; } 126 | .ui-icon-arrow-1-nw { background-position: -112px -32px; } 127 | .ui-icon-arrow-2-n-s { background-position: -128px -32px; } 128 | .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } 129 | .ui-icon-arrow-2-e-w { background-position: -160px -32px; } 130 | .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } 131 | .ui-icon-arrowstop-1-n { background-position: -192px -32px; } 132 | .ui-icon-arrowstop-1-e { background-position: -208px -32px; } 133 | .ui-icon-arrowstop-1-s { background-position: -224px -32px; } 134 | .ui-icon-arrowstop-1-w { background-position: -240px -32px; } 135 | .ui-icon-arrowthick-1-n { background-position: 0 -48px; } 136 | .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } 137 | .ui-icon-arrowthick-1-e { background-position: -32px -48px; } 138 | .ui-icon-arrowthick-1-se { background-position: -48px -48px; } 139 | .ui-icon-arrowthick-1-s { background-position: -64px -48px; } 140 | .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } 141 | .ui-icon-arrowthick-1-w { background-position: -96px -48px; } 142 | .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } 143 | .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } 144 | .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } 145 | .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } 146 | .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } 147 | .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } 148 | .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } 149 | .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } 150 | .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } 151 | .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } 152 | .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } 153 | .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } 154 | .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } 155 | .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } 156 | .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } 157 | .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } 158 | .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } 159 | .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } 160 | .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } 161 | .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } 162 | .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } 163 | .ui-icon-arrow-4 { background-position: 0 -80px; } 164 | .ui-icon-arrow-4-diag { background-position: -16px -80px; } 165 | .ui-icon-extlink { background-position: -32px -80px; } 166 | .ui-icon-newwin { background-position: -48px -80px; } 167 | .ui-icon-refresh { background-position: -64px -80px; } 168 | .ui-icon-shuffle { background-position: -80px -80px; } 169 | .ui-icon-transfer-e-w { background-position: -96px -80px; } 170 | .ui-icon-transferthick-e-w { background-position: -112px -80px; } 171 | .ui-icon-folder-collapsed { background-position: 0 -96px; } 172 | .ui-icon-folder-open { background-position: -16px -96px; } 173 | .ui-icon-document { background-position: -32px -96px; } 174 | .ui-icon-document-b { background-position: -48px -96px; } 175 | .ui-icon-note { background-position: -64px -96px; } 176 | .ui-icon-mail-closed { background-position: -80px -96px; } 177 | .ui-icon-mail-open { background-position: -96px -96px; } 178 | .ui-icon-suitcase { background-position: -112px -96px; } 179 | .ui-icon-comment { background-position: -128px -96px; } 180 | .ui-icon-person { background-position: -144px -96px; } 181 | .ui-icon-print { background-position: -160px -96px; } 182 | .ui-icon-trash { background-position: -176px -96px; } 183 | .ui-icon-locked { background-position: -192px -96px; } 184 | .ui-icon-unlocked { background-position: -208px -96px; } 185 | .ui-icon-bookmark { background-position: -224px -96px; } 186 | .ui-icon-tag { background-position: -240px -96px; } 187 | .ui-icon-home { background-position: 0 -112px; } 188 | .ui-icon-flag { background-position: -16px -112px; } 189 | .ui-icon-calendar { background-position: -32px -112px; } 190 | .ui-icon-cart { background-position: -48px -112px; } 191 | .ui-icon-pencil { background-position: -64px -112px; } 192 | .ui-icon-clock { background-position: -80px -112px; } 193 | .ui-icon-disk { background-position: -96px -112px; } 194 | .ui-icon-calculator { background-position: -112px -112px; } 195 | .ui-icon-zoomin { background-position: -128px -112px; } 196 | .ui-icon-zoomout { background-position: -144px -112px; } 197 | .ui-icon-search { background-position: -160px -112px; } 198 | .ui-icon-wrench { background-position: -176px -112px; } 199 | .ui-icon-gear { background-position: -192px -112px; } 200 | .ui-icon-heart { background-position: -208px -112px; } 201 | .ui-icon-star { background-position: -224px -112px; } 202 | .ui-icon-link { background-position: -240px -112px; } 203 | .ui-icon-cancel { background-position: 0 -128px; } 204 | .ui-icon-plus { background-position: -16px -128px; } 205 | .ui-icon-plusthick { background-position: -32px -128px; } 206 | .ui-icon-minus { background-position: -48px -128px; } 207 | .ui-icon-minusthick { background-position: -64px -128px; } 208 | .ui-icon-close { background-position: -80px -128px; } 209 | .ui-icon-closethick { background-position: -96px -128px; } 210 | .ui-icon-key { background-position: -112px -128px; } 211 | .ui-icon-lightbulb { background-position: -128px -128px; } 212 | .ui-icon-scissors { background-position: -144px -128px; } 213 | .ui-icon-clipboard { background-position: -160px -128px; } 214 | .ui-icon-copy { background-position: -176px -128px; } 215 | .ui-icon-contact { background-position: -192px -128px; } 216 | .ui-icon-image { background-position: -208px -128px; } 217 | .ui-icon-video { background-position: -224px -128px; } 218 | .ui-icon-script { background-position: -240px -128px; } 219 | .ui-icon-alert { background-position: 0 -144px; } 220 | .ui-icon-info { background-position: -16px -144px; } 221 | .ui-icon-notice { background-position: -32px -144px; } 222 | .ui-icon-help { background-position: -48px -144px; } 223 | .ui-icon-check { background-position: -64px -144px; } 224 | .ui-icon-bullet { background-position: -80px -144px; } 225 | .ui-icon-radio-off { background-position: -96px -144px; } 226 | .ui-icon-radio-on { background-position: -112px -144px; } 227 | .ui-icon-pin-w { background-position: -128px -144px; } 228 | .ui-icon-pin-s { background-position: -144px -144px; } 229 | .ui-icon-play { background-position: 0 -160px; } 230 | .ui-icon-pause { background-position: -16px -160px; } 231 | .ui-icon-seek-next { background-position: -32px -160px; } 232 | .ui-icon-seek-prev { background-position: -48px -160px; } 233 | .ui-icon-seek-end { background-position: -64px -160px; } 234 | .ui-icon-seek-start { background-position: -80px -160px; } 235 | /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ 236 | .ui-icon-seek-first { background-position: -80px -160px; } 237 | .ui-icon-stop { background-position: -96px -160px; } 238 | .ui-icon-eject { background-position: -112px -160px; } 239 | .ui-icon-volume-off { background-position: -128px -160px; } 240 | .ui-icon-volume-on { background-position: -144px -160px; } 241 | .ui-icon-power { background-position: 0 -176px; } 242 | .ui-icon-signal-diag { background-position: -16px -176px; } 243 | .ui-icon-signal { background-position: -32px -176px; } 244 | .ui-icon-battery-0 { background-position: -48px -176px; } 245 | .ui-icon-battery-1 { background-position: -64px -176px; } 246 | .ui-icon-battery-2 { background-position: -80px -176px; } 247 | .ui-icon-battery-3 { background-position: -96px -176px; } 248 | .ui-icon-circle-plus { background-position: 0 -192px; } 249 | .ui-icon-circle-minus { background-position: -16px -192px; } 250 | .ui-icon-circle-close { background-position: -32px -192px; } 251 | .ui-icon-circle-triangle-e { background-position: -48px -192px; } 252 | .ui-icon-circle-triangle-s { background-position: -64px -192px; } 253 | .ui-icon-circle-triangle-w { background-position: -80px -192px; } 254 | .ui-icon-circle-triangle-n { background-position: -96px -192px; } 255 | .ui-icon-circle-arrow-e { background-position: -112px -192px; } 256 | .ui-icon-circle-arrow-s { background-position: -128px -192px; } 257 | .ui-icon-circle-arrow-w { background-position: -144px -192px; } 258 | .ui-icon-circle-arrow-n { background-position: -160px -192px; } 259 | .ui-icon-circle-zoomin { background-position: -176px -192px; } 260 | .ui-icon-circle-zoomout { background-position: -192px -192px; } 261 | .ui-icon-circle-check { background-position: -208px -192px; } 262 | .ui-icon-circlesmall-plus { background-position: 0 -208px; } 263 | .ui-icon-circlesmall-minus { background-position: -16px -208px; } 264 | .ui-icon-circlesmall-close { background-position: -32px -208px; } 265 | .ui-icon-squaresmall-plus { background-position: -48px -208px; } 266 | .ui-icon-squaresmall-minus { background-position: -64px -208px; } 267 | .ui-icon-squaresmall-close { background-position: -80px -208px; } 268 | .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } 269 | .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } 270 | .ui-icon-grip-solid-vertical { background-position: -32px -224px; } 271 | .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } 272 | .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } 273 | .ui-icon-grip-diagonal-se { background-position: -80px -224px; } 274 | 275 | 276 | /* Misc visuals 277 | ----------------------------------*/ 278 | 279 | /* Corner radius */ 280 | .ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -khtml-border-top-left-radius: 6px; border-top-left-radius: 6px; } 281 | .ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; -khtml-border-top-right-radius: 6px; border-top-right-radius: 6px; } 282 | .ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; -khtml-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; } 283 | .ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; -khtml-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; } 284 | /* Overlays */ 285 | .ui-widget-overlay { background: #444444 url(images/ui-bg_diagonals-thick_15_444444_40x40.png) 50% 50% repeat; opacity: .30;filter:Alpha(Opacity=30); } 286 | .ui-widget-shadow { margin: 4px 0 0 4px; padding: 0px; background: #aaaaaa url(images/ui-bg_diagonals-small_0_aaaaaa_40x40.png) 50% 50% repeat; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 4px; -khtml-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }/*! 287 | * jQuery UI Resizable 1.8.20 288 | * 289 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 290 | * Dual licensed under the MIT or GPL Version 2 licenses. 291 | * http://jquery.org/license 292 | * 293 | * http://docs.jquery.com/UI/Resizable#theming 294 | */ 295 | .ui-resizable { position: relative;} 296 | .ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; } 297 | .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } 298 | .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } 299 | .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } 300 | .ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } 301 | .ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } 302 | .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } 303 | .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } 304 | .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } 305 | .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*! 306 | * jQuery UI Selectable 1.8.20 307 | * 308 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 309 | * Dual licensed under the MIT or GPL Version 2 licenses. 310 | * http://jquery.org/license 311 | * 312 | * http://docs.jquery.com/UI/Selectable#theming 313 | */ 314 | .ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } 315 | /*! 316 | * jQuery UI Accordion 1.8.20 317 | * 318 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 319 | * Dual licensed under the MIT or GPL Version 2 licenses. 320 | * http://jquery.org/license 321 | * 322 | * http://docs.jquery.com/UI/Accordion#theming 323 | */ 324 | /* IE/Win - Fix animation bug - #4615 */ 325 | .ui-accordion { width: 100%; } 326 | .ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } 327 | .ui-accordion .ui-accordion-li-fix { display: inline; } 328 | .ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } 329 | .ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } 330 | .ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } 331 | .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } 332 | .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } 333 | .ui-accordion .ui-accordion-content-active { display: block; } 334 | /*! 335 | * jQuery UI Autocomplete 1.8.20 336 | * 337 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 338 | * Dual licensed under the MIT or GPL Version 2 licenses. 339 | * http://jquery.org/license 340 | * 341 | * http://docs.jquery.com/UI/Autocomplete#theming 342 | */ 343 | .ui-autocomplete { position: absolute; cursor: default; } 344 | 345 | /* workarounds */ 346 | * html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ 347 | 348 | /* 349 | * jQuery UI Menu 1.8.20 350 | * 351 | * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) 352 | * Dual licensed under the MIT or GPL Version 2 licenses. 353 | * http://jquery.org/license 354 | * 355 | * http://docs.jquery.com/UI/Menu#theming 356 | */ 357 | .ui-menu { 358 | list-style:none; 359 | padding: 2px; 360 | margin: 0; 361 | display:block; 362 | float: left; 363 | } 364 | .ui-menu .ui-menu { 365 | margin-top: -3px; 366 | } 367 | .ui-menu .ui-menu-item { 368 | margin:0; 369 | padding: 0; 370 | zoom: 1; 371 | float: left; 372 | clear: left; 373 | width: 100%; 374 | } 375 | .ui-menu .ui-menu-item a { 376 | text-decoration:none; 377 | display:block; 378 | padding:.2em .4em; 379 | line-height:1.5; 380 | zoom:1; 381 | } 382 | .ui-menu .ui-menu-item a.ui-state-hover, 383 | .ui-menu .ui-menu-item a.ui-state-active { 384 | font-weight: normal; 385 | margin: -1px; 386 | } 387 | /*! 388 | * jQuery UI Button 1.8.20 389 | * 390 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 391 | * Dual licensed under the MIT or GPL Version 2 licenses. 392 | * http://jquery.org/license 393 | * 394 | * http://docs.jquery.com/UI/Button#theming 395 | */ 396 | .ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ 397 | .ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ 398 | button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ 399 | .ui-button-icons-only { width: 3.4em; } 400 | button.ui-button-icons-only { width: 3.7em; } 401 | 402 | /*button text element */ 403 | .ui-button .ui-button-text { display: block; line-height: 1.4; } 404 | .ui-button-text-only .ui-button-text { padding: .4em 1em; } 405 | .ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } 406 | .ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } 407 | .ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } 408 | .ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } 409 | /* no icon support for input elements, provide padding by default */ 410 | input.ui-button { padding: .4em 1em; } 411 | 412 | /*button icon element(s) */ 413 | .ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } 414 | .ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } 415 | .ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } 416 | .ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } 417 | .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } 418 | 419 | /*button sets*/ 420 | .ui-buttonset { margin-right: 7px; } 421 | .ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } 422 | 423 | /* workarounds */ 424 | button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ 425 | /*! 426 | * jQuery UI Dialog 1.8.20 427 | * 428 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 429 | * Dual licensed under the MIT or GPL Version 2 licenses. 430 | * http://jquery.org/license 431 | * 432 | * http://docs.jquery.com/UI/Dialog#theming 433 | */ 434 | .ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } 435 | .ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } 436 | .ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } 437 | .ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } 438 | .ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } 439 | .ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } 440 | .ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } 441 | .ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } 442 | .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } 443 | .ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } 444 | .ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } 445 | .ui-draggable .ui-dialog-titlebar { cursor: move; } 446 | /*! 447 | * jQuery UI Slider 1.8.20 448 | * 449 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 450 | * Dual licensed under the MIT or GPL Version 2 licenses. 451 | * http://jquery.org/license 452 | * 453 | * http://docs.jquery.com/UI/Slider#theming 454 | */ 455 | .ui-slider { position: relative; text-align: left; } 456 | .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } 457 | .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } 458 | 459 | .ui-slider-horizontal { height: .8em; } 460 | .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } 461 | .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } 462 | .ui-slider-horizontal .ui-slider-range-min { left: 0; } 463 | .ui-slider-horizontal .ui-slider-range-max { right: 0; } 464 | 465 | .ui-slider-vertical { width: .8em; height: 100px; } 466 | .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } 467 | .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } 468 | .ui-slider-vertical .ui-slider-range-min { bottom: 0; } 469 | .ui-slider-vertical .ui-slider-range-max { top: 0; }/*! 470 | * jQuery UI Tabs 1.8.20 471 | * 472 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 473 | * Dual licensed under the MIT or GPL Version 2 licenses. 474 | * http://jquery.org/license 475 | * 476 | * http://docs.jquery.com/UI/Tabs#theming 477 | */ 478 | .ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ 479 | .ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } 480 | .ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } 481 | .ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } 482 | .ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } 483 | .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } 484 | .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ 485 | .ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } 486 | .ui-tabs .ui-tabs-hide { display: none !important; } 487 | /*! 488 | * jQuery UI Datepicker 1.8.20 489 | * 490 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 491 | * Dual licensed under the MIT or GPL Version 2 licenses. 492 | * http://jquery.org/license 493 | * 494 | * http://docs.jquery.com/UI/Datepicker#theming 495 | */ 496 | .ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } 497 | .ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } 498 | .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } 499 | .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } 500 | .ui-datepicker .ui-datepicker-prev { left:2px; } 501 | .ui-datepicker .ui-datepicker-next { right:2px; } 502 | .ui-datepicker .ui-datepicker-prev-hover { left:1px; } 503 | .ui-datepicker .ui-datepicker-next-hover { right:1px; } 504 | .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } 505 | .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } 506 | .ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } 507 | .ui-datepicker select.ui-datepicker-month-year {width: 100%;} 508 | .ui-datepicker select.ui-datepicker-month, 509 | .ui-datepicker select.ui-datepicker-year { width: 49%;} 510 | .ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } 511 | .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } 512 | .ui-datepicker td { border: 0; padding: 1px; } 513 | .ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } 514 | .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } 515 | .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } 516 | .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } 517 | 518 | /* with multiple calendars */ 519 | .ui-datepicker.ui-datepicker-multi { width:auto; } 520 | .ui-datepicker-multi .ui-datepicker-group { float:left; } 521 | .ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } 522 | .ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } 523 | .ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } 524 | .ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } 525 | .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } 526 | .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } 527 | .ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } 528 | .ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } 529 | 530 | /* RTL support */ 531 | .ui-datepicker-rtl { direction: rtl; } 532 | .ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } 533 | .ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } 534 | .ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } 535 | .ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } 536 | .ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } 537 | .ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } 538 | .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } 539 | .ui-datepicker-rtl .ui-datepicker-group { float:right; } 540 | .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } 541 | .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } 542 | 543 | /* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ 544 | .ui-datepicker-cover { 545 | display: none; /*sorry for IE5*/ 546 | display/**/: block; /*sorry for IE5*/ 547 | position: absolute; /*must have*/ 548 | z-index: -1; /*must have*/ 549 | filter: mask(); /*must have*/ 550 | top: -4px; /*must have*/ 551 | left: -4px; /*must have*/ 552 | width: 200px; /*must have*/ 553 | height: 200px; /*must have*/ 554 | }/*! 555 | * jQuery UI Progressbar 1.8.20 556 | * 557 | * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) 558 | * Dual licensed under the MIT or GPL Version 2 licenses. 559 | * http://jquery.org/license 560 | * 561 | * http://docs.jquery.com/UI/Progressbar#theming 562 | */ 563 | .ui-progressbar { height:2em; text-align: left; overflow: hidden; } 564 | .ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } -------------------------------------------------------------------------------- /css/jquery.jqChart.css: -------------------------------------------------------------------------------- 1 | .ui-jqchart { position: relative; } 2 | 3 | .ui-jqchart .ui-jqchart-toolbar { position: absolute; margin: 0; padding: 2px; list-style-type: none; white-space: nowrap; } 4 | .ui-jqchart .ui-jqchart-toolbar li { display: none; margin: 0 2px; padding: 2px 0; cursor: pointer; float: left; } 5 | .ui-jqchart .ui-jqchart-toolbar span.ui-icon { float: left; margin: 0 2px; } 6 | .ui-jqchart .ui-jqchart-toolbar-separator { height: 16px; width: 1px; } 7 | 8 | /*.ui-jqchart .ui-jqchart-tooltip { position: absolute; white-space: nowrap; padding: .2em .4em; z-index: 9999; border: 1px solid #dddddd; color: #333333; background: white; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; -o-box-shadow: 0 0 5px #aaa; -moz-box-shadow: 0 0 5px #aaa; -webkit-box-shadow: 0 0 5px #aaa; box-shadow: 0 0 5px #aaa; }*/ 9 | 10 | /** html .ui-jqchart .ui-jqchart-tooltip { background-image: none; } 11 | body .ui-jqchart .ui-jqchart-tooltip { border-width: 2px; }*/ 12 | -------------------------------------------------------------------------------- /css/jquery.jqRangeSlider.css: -------------------------------------------------------------------------------- 1 | .ui-jqrangeslider { position: relative; } 2 | 3 | .ui-jqrangeslider .ui-jqrangeslider-arrow-left { position: absolute; width: 18px; cursor: pointer; vertical-align: middle; } 4 | .ui-jqrangeslider .ui-jqrangeslider-arrow-icon-left { position: absolute; } 5 | .ui-jqrangeslider .ui-jqrangeslider-arrow-right { position: absolute; width: 18px; cursor: pointer; } 6 | .ui-jqrangeslider .ui-jqrangeslider-arrow-icon-right { position: absolute; } 7 | .ui-jqrangeslider .ui-jqrangeslider-handle-left { position: absolute; width: 12px; cursor: ew-resize; } 8 | .ui-jqrangeslider .ui-jqrangeslider-handle-icon-left { position: absolute; } 9 | .ui-jqrangeslider .ui-jqrangeslider-handle-right { position: absolute; width: 12px; cursor: ew-resize; } 10 | .ui-jqrangeslider .ui-jqrangeslider-handle-icon-right { position: absolute; } 11 | .ui-jqrangeslider .ui-jqrangeslider-slider-horizontal { position: absolute; cursor: move; cursor: grab; cursor: -moz-grab; } 12 | .ui-jqrangeslider .ui-jqrangeslider-slider-horizontal-dragging { cursor: -moz-grabbing; cursor: grabbing; } 13 | .ui-jqrangeslider .ui-jqrangeslider-background-horizontal { position: absolute; } 14 | .ui-jqrangeslider .ui-jqrangeslider-background-horizontal-left { position: absolute; } 15 | .ui-jqrangeslider .ui-jqrangeslider-background-horizontal-right { position: absolute; } 16 | 17 | .ui-jqrangeslider .ui-jqrangeslider-arrow-bottom { position: absolute; height: 18px; cursor: pointer; } 18 | .ui-jqrangeslider .ui-jqrangeslider-arrow-icon-bottom { position: absolute; } 19 | .ui-jqrangeslider .ui-jqrangeslider-arrow-top { position: absolute; height: 18px; cursor: pointer; } 20 | .ui-jqrangeslider .ui-jqrangeslider-arrow-icon-top { position: absolute; } 21 | .ui-jqrangeslider .ui-jqrangeslider-handle-bottom { position: absolute; height: 12px; cursor: ns-resize; } 22 | .ui-jqrangeslider .ui-jqrangeslider-handle-icon-bottom { position: absolute; } 23 | .ui-jqrangeslider .ui-jqrangeslider-handle-top { position: absolute; height: 12px; cursor: ns-resize; } 24 | .ui-jqrangeslider .ui-jqrangeslider-handle-icon-top { position: absolute; } 25 | .ui-jqrangeslider .ui-jqrangeslider-slider-vertical { position: absolute; cursor: move; cursor: grab; cursor: -moz-grab; } 26 | .ui-jqrangeslider .ui-jqrangeslider-slider-vertical-dragging { cursor: -moz-grabbing; cursor: grabbing; } 27 | .ui-jqrangeslider .ui-jqrangeslider-background-vertical { position: absolute; } 28 | .ui-jqrangeslider .ui-jqrangeslider-background-vertical-bottom { position: absolute; } 29 | .ui-jqrangeslider .ui-jqrangeslider-background-vertical-top { position: absolute; } 30 | -------------------------------------------------------------------------------- /css/table.css: -------------------------------------------------------------------------------- 1 | body {margin: 5px; padding: 0px} 2 | table { 3 | border-width: 1px; 4 | border-spacing: 2px; 5 | border-style: outset; 6 | border-color: gray; 7 | border-collapse:collapse; 8 | background-color: white; 9 | font-size: 14px; 10 | width: 100%; 11 | } 12 | th { 13 | white-space: nowrap; 14 | text-align: center; 15 | background-color: black; 16 | color: white; 17 | } 18 | td { 19 | white-space: nowrap; 20 | text-align: right; 21 | width: 50px; 22 | padding-right: 3px; 23 | } 24 | td.c { 25 | text-align: center; 26 | background-color: #d0d0d0; 27 | color: blue; 28 | } 29 | td.d { 30 | padding:4px 0 ; 31 | text-align: center; 32 | background-color: #d0d0d0; 33 | color: black; 34 | font-size:12px; 35 | } 36 | td.err { 37 | text-align: center; 38 | background-color: #e0e0ff; 39 | color: red; 40 | } 41 | -------------------------------------------------------------------------------- /icon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtimus/GoxTradingBot/85a67d27b856949cf27440ae77a56d4a83e0bfbe/icon.gif -------------------------------------------------------------------------------- /icon_128.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtimus/GoxTradingBot/85a67d27b856949cf27440ae77a56d4a83e0bfbe/icon_128.gif -------------------------------------------------------------------------------- /img/chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtimus/GoxTradingBot/85a67d27b856949cf27440ae77a56d4a83e0bfbe/img/chart.png -------------------------------------------------------------------------------- /img/options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtimus/GoxTradingBot/85a67d27b856949cf27440ae77a56d4a83e0bfbe/img/options.png -------------------------------------------------------------------------------- /js/chart.js: -------------------------------------------------------------------------------- 1 | var bp = chrome.extension.getBackgroundPage() 2 | var chartInitialized = false; 3 | var nowDate; 4 | var nowDateStr; 5 | 6 | 7 | function padit(d) {return d<10 ? '0'+d.toString() : d.toString()}; 8 | 9 | function formatChartNumbers(v) { 10 | return v.toFixed(4); 11 | } 12 | 13 | function processTradeData(emaLong, h1, emaShort, tim) { 14 | var refr = false 15 | var done = true 16 | try { 17 | 18 | data1 = []; 19 | data2 = []; 20 | data3 = []; 21 | 22 | nowDate=new Date(); 23 | nowDateStr=nowDate.getFullYear()+"-"+padit(nowDate.getMonth()+1)+"-"+padit(nowDate.getDate()); 24 | 25 | //console.log(req.responseText) 26 | ///var trs = bp.H1;//responseData;//JSON.parse(responseText ) 27 | //console.log(trs.length) 28 | if (h1.length > 1) { 29 | var ss = new Date(); 30 | for (var i = 0; i < h1.length; i++) { 31 | ss=new Date(tim[i]*bp.TimeFrame*1000);//(new Date(bp.tim[i]*3600*1000)).getHours();// + ":00"; 32 | 33 | if (emaLong!=null){ 34 | data1.push([ss, parseFloat(emaLong[i])]); 35 | } 36 | 37 | data2.push([ss, parseFloat(h1[i])]); 38 | 39 | if (emaShort!=null){ 40 | data3.push([ss, parseFloat(emaShort[i])]); 41 | } 42 | 43 | } 44 | 45 | var background = { 46 | type: 'linearGradient', 47 | x0: 0, 48 | y0: 0, 49 | x1: 0, 50 | y1: 1, 51 | colorStops: [{ offset: 0, color: '#d2e6c9' }, 52 | { offset: 1, color: 'white'} 53 | ] 54 | }; 55 | 56 | //$('#jqChart').empty(); 57 | if (chartInitialized){ 58 | var series = $('#jqChart').jqChart('option', 'series'); 59 | 60 | series[0].data = data1; 61 | series[1].data = data2; 62 | series[2].data = data3; 63 | 64 | $('#jqChart').jqChart('update'); 65 | } 66 | else { 67 | $('#jqChart').jqChart({ 68 | title: { text: 'EMA Trends.', font: '18px sans-serif' }, 69 | axes: [ 70 | { 71 | type: 'dateTime', 72 | interval: 1, 73 | intervalType: 'hours', 74 | labels: { stringFormat: 'HH:MM' },//mm/dd 75 | location: 'bottom', 76 | zoomEnabled: true 77 | } 78 | ], 79 | border: { strokeStyle: '#6ba851' }, 80 | background: background, 81 | tooltips: { 82 | type: 'shared' 83 | }, 84 | crosshairs: { 85 | enabled: true, 86 | hLine: false, 87 | vLine: { strokeStyle: '#cc0a0c' } 88 | }, 89 | series: [ 90 | { 91 | title: 'emaShort', 92 | type: 'line', 93 | data: data1, 94 | markers: null 95 | }, 96 | { 97 | title: 'Price', 98 | type: 'line', 99 | data: data2, 100 | markers: null 101 | }, 102 | { 103 | title: 'emaLong', 104 | type: 'line', 105 | data: data3, 106 | markers: null 107 | } 108 | ] 109 | }); 110 | 111 | $('#jqChart').bind('tooltipFormat', function (e, data) { 112 | 113 | var trend=(data[2].yUP':(data[2].y>data[0].y?'DOWN':'none')); 114 | 115 | var d=data[0].x;//new Date(data[0].x*60*1000); 116 | var dateStr=d.getFullYear()+"-"+padit(d.getMonth()+1)+"-"+padit(d.getDate()); 117 | var t=(dateStr!=nowDateStr?dateStr:"Today")+" "+padit(d.getHours()) + ":"+padit(d.getMinutes()); 118 | var dateHtml = '
'+t+''; 119 | 120 | var emaShortHtml = ''; 121 | 122 | var emaLongHtml = '
Price: '+formatChartNumbers(data[1].y)+'
EMA'+bp.EmaShortPar+': '+formatChartNumbers(data[0].y)+'
EMA'+bp.EmaLongPar+': '+formatChartNumbers(data[2].y)+'
Trend: '+trend; 123 | return dateHtml + emaShortHtml + emaLongHtml; 124 | /*return "" + data[0].series.title + "
" + 125 | "X = " + data[0].x + "
" + 126 | "Y = " + data[0].y + "
" + 127 | "Size = " + data[0].size + "
"+ 128 | "Trend = " + trend + "
";*/ 129 | }); 130 | 131 | 132 | chartInitialized = true; 133 | }//initialized 134 | 135 | } 136 | 137 | } catch (e) { 138 | console.log("getTrades JSON error", e, e.message) 139 | chrome.browserAction.setBadgeText({text: "xxx"}) 140 | } 141 | 142 | } 143 | 144 | 145 | function showTrades(){ 146 | 147 | if (!bp.updateinprogress && bp.H1.length>bp.LogLines) { 148 | processTradeData(bp.emaShort,bp.H1,bp.emaLong,bp.tim); 149 | } 150 | 151 | } 152 | 153 | function showTradesHist(){ 154 | console.log("showTradesHist"); 155 | 156 | bp.getWalletHistory(function(rdo){ 157 | 158 | var recNum = parseInt(rdo.return.records); 159 | var tab = document.getElementById("tab"); 160 | tab.style.display="inline"; 161 | while (tab.rows.length>1) tab.deleteRow(1) 162 | for (var i=0; i elements as element.getContext(). 56 | * @this {HTMLElement} 57 | * @return {CanvasRenderingContext2D_} 58 | */ 59 | function getContext() 60 | { 61 | return this.context_ || 62 | (this.context_ = new CanvasRenderingContext2D_(this)); 63 | } 64 | 65 | var slice = Array.prototype.slice; 66 | 67 | /** 68 | * Binds a function to an object. The returned function will always use the 69 | * passed in {@code obj} as {@code this}. 70 | * 71 | * Example: 72 | * 73 | * g = bind(f, obj, a, b) 74 | * g(c, d) // will do f.call(obj, a, b, c, d) 75 | * 76 | * @param {Function} f The function to bind the object to 77 | * @param {Object} obj The object that should act as this when the function 78 | * is called 79 | * @param {*} var_args Rest arguments that will be used as the initial 80 | * arguments when the function is called 81 | * @return {Function} A new function that has bound this 82 | */ 83 | function bind(f, obj, var_args) 84 | { 85 | var a = slice.call(arguments, 2); 86 | return function () 87 | { 88 | return f.apply(obj, a.concat(slice.call(arguments))); 89 | }; 90 | } 91 | 92 | function encodeHtmlAttribute(s) 93 | { 94 | return String(s).replace(/&/g, '&').replace(/"/g, '"'); 95 | } 96 | 97 | function addNamespace(doc, prefix, urn) 98 | { 99 | if (!doc.namespaces[prefix]) { 100 | doc.namespaces.add(prefix, urn, '#default#VML'); 101 | } 102 | } 103 | 104 | function addNamespacesAndStylesheet(doc) 105 | { 106 | addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml'); 107 | addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office'); 108 | 109 | // Setup default CSS. Only add one style sheet per document 110 | if (!doc.styleSheets['ex_canvas_']) { 111 | var ss = doc.createStyleSheet(); 112 | ss.owningElement.id = 'ex_canvas_'; 113 | ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + 114 | // default size is 300x150 in Gecko and Opera 115 | 'text-align:left;width:300px;height:150px}'; 116 | } 117 | } 118 | 119 | // Add namespaces and stylesheet at startup. 120 | addNamespacesAndStylesheet(document); 121 | 122 | var G_vmlCanvasManager_ = { 123 | init: function (opt_doc) 124 | { 125 | var doc = opt_doc || document; 126 | // Create a dummy element so that IE will allow canvas elements to be 127 | // recognized. 128 | doc.createElement('canvas'); 129 | doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); 130 | }, 131 | 132 | init_: function (doc) 133 | { 134 | // find all canvas elements 135 | var els = doc.getElementsByTagName('canvas'); 136 | for (var i = 0; i < els.length; i++) { 137 | this.initElement(els[i]); 138 | } 139 | }, 140 | 141 | /** 142 | * Public initializes a canvas element so that it can be used as canvas 143 | * element from now on. This is called automatically before the page is 144 | * loaded but if you are creating elements using createElement you need to 145 | * make sure this is called on the element. 146 | * @param {HTMLElement} el The canvas element to initialize. 147 | * @return {HTMLElement} the element that was created. 148 | */ 149 | initElement: function (el) 150 | { 151 | if (!el.getContext) { 152 | el.getContext = getContext; 153 | 154 | // Add namespaces and stylesheet to document of the element. 155 | addNamespacesAndStylesheet(el.ownerDocument); 156 | 157 | // Remove fallback content. There is no way to hide text nodes so we 158 | // just remove all childNodes. We could hide all elements and remove 159 | // text nodes but who really cares about the fallback content. 160 | el.innerHTML = ''; 161 | 162 | // do not use inline function because that will leak memory 163 | el.attachEvent('onpropertychange', onPropertyChange); 164 | el.attachEvent('onresize', onResize); 165 | 166 | var attrs = el.attributes; 167 | if (attrs.width && attrs.width.specified) { 168 | // TODO: use runtimeStyle and coordsize 169 | // el.getContext().setWidth_(attrs.width.nodeValue); 170 | el.style.width = attrs.width.nodeValue + 'px'; 171 | } else { 172 | el.width = el.clientWidth; 173 | } 174 | if (attrs.height && attrs.height.specified) { 175 | // TODO: use runtimeStyle and coordsize 176 | // el.getContext().setHeight_(attrs.height.nodeValue); 177 | el.style.height = attrs.height.nodeValue + 'px'; 178 | } else { 179 | el.height = el.clientHeight; 180 | } 181 | //el.getContext().setCoordsize_() 182 | } 183 | return el; 184 | } 185 | }; 186 | 187 | function onPropertyChange(e) 188 | { 189 | var el = e.srcElement; 190 | 191 | switch (e.propertyName) { 192 | case 'width': 193 | el.getContext().clearRect(); 194 | el.style.width = el.attributes.width.nodeValue + 'px'; 195 | // In IE8 this does not trigger onresize. 196 | el.firstChild.style.width = el.clientWidth + 'px'; 197 | break; 198 | case 'height': 199 | el.getContext().clearRect(); 200 | el.style.height = el.attributes.height.nodeValue + 'px'; 201 | el.firstChild.style.height = el.clientHeight + 'px'; 202 | break; 203 | } 204 | } 205 | 206 | function onResize(e) 207 | { 208 | var el = e.srcElement; 209 | if (el.firstChild) { 210 | el.firstChild.style.width = el.clientWidth + 'px'; 211 | el.firstChild.style.height = el.clientHeight + 'px'; 212 | } 213 | } 214 | 215 | G_vmlCanvasManager_.init(); 216 | 217 | // precompute "00" to "FF" 218 | var decToHex = []; 219 | for (var i = 0; i < 16; i++) { 220 | for (var j = 0; j < 16; j++) { 221 | decToHex[i * 16 + j] = i.toString(16) + j.toString(16); 222 | } 223 | } 224 | 225 | function createMatrixIdentity() 226 | { 227 | return [ 228 | [1, 0, 0], 229 | [0, 1, 0], 230 | [0, 0, 1] 231 | ]; 232 | } 233 | 234 | function matrixMultiply(m1, m2) 235 | { 236 | var result = createMatrixIdentity(); 237 | 238 | for (var x = 0; x < 3; x++) { 239 | for (var y = 0; y < 3; y++) { 240 | var sum = 0; 241 | 242 | for (var z = 0; z < 3; z++) { 243 | sum += m1[x][z] * m2[z][y]; 244 | } 245 | 246 | result[x][y] = sum; 247 | } 248 | } 249 | return result; 250 | } 251 | 252 | function copyState(o1, o2) 253 | { 254 | o2.fillStyle = o1.fillStyle; 255 | o2.lineCap = o1.lineCap; 256 | o2.lineJoin = o1.lineJoin; 257 | o2.lineWidth = o1.lineWidth; 258 | o2.miterLimit = o1.miterLimit; 259 | o2.shadowBlur = o1.shadowBlur; 260 | o2.shadowColor = o1.shadowColor; 261 | o2.shadowOffsetX = o1.shadowOffsetX; 262 | o2.shadowOffsetY = o1.shadowOffsetY; 263 | o2.strokeStyle = o1.strokeStyle; 264 | o2.globalAlpha = o1.globalAlpha; 265 | o2.font = o1.font; 266 | o2.textAlign = o1.textAlign; 267 | o2.textBaseline = o1.textBaseline; 268 | o2.arcScaleX_ = o1.arcScaleX_; 269 | o2.arcScaleY_ = o1.arcScaleY_; 270 | o2.lineScale_ = o1.lineScale_; 271 | } 272 | 273 | var colorData = { 274 | aliceblue: '#F0F8FF', 275 | antiquewhite: '#FAEBD7', 276 | aquamarine: '#7FFFD4', 277 | azure: '#F0FFFF', 278 | beige: '#F5F5DC', 279 | bisque: '#FFE4C4', 280 | black: '#000000', 281 | blanchedalmond: '#FFEBCD', 282 | blueviolet: '#8A2BE2', 283 | brown: '#A52A2A', 284 | burlywood: '#DEB887', 285 | cadetblue: '#5F9EA0', 286 | chartreuse: '#7FFF00', 287 | chocolate: '#D2691E', 288 | coral: '#FF7F50', 289 | cornflowerblue: '#6495ED', 290 | cornsilk: '#FFF8DC', 291 | crimson: '#DC143C', 292 | cyan: '#00FFFF', 293 | darkblue: '#00008B', 294 | darkcyan: '#008B8B', 295 | darkgoldenrod: '#B8860B', 296 | darkgray: '#A9A9A9', 297 | darkgreen: '#006400', 298 | darkgrey: '#A9A9A9', 299 | darkkhaki: '#BDB76B', 300 | darkmagenta: '#8B008B', 301 | darkolivegreen: '#556B2F', 302 | darkorange: '#FF8C00', 303 | darkorchid: '#9932CC', 304 | darkred: '#8B0000', 305 | darksalmon: '#E9967A', 306 | darkseagreen: '#8FBC8F', 307 | darkslateblue: '#483D8B', 308 | darkslategray: '#2F4F4F', 309 | darkslategrey: '#2F4F4F', 310 | darkturquoise: '#00CED1', 311 | darkviolet: '#9400D3', 312 | deeppink: '#FF1493', 313 | deepskyblue: '#00BFFF', 314 | dimgray: '#696969', 315 | dimgrey: '#696969', 316 | dodgerblue: '#1E90FF', 317 | firebrick: '#B22222', 318 | floralwhite: '#FFFAF0', 319 | forestgreen: '#228B22', 320 | gainsboro: '#DCDCDC', 321 | ghostwhite: '#F8F8FF', 322 | gold: '#FFD700', 323 | goldenrod: '#DAA520', 324 | grey: '#808080', 325 | greenyellow: '#ADFF2F', 326 | honeydew: '#F0FFF0', 327 | hotpink: '#FF69B4', 328 | indianred: '#CD5C5C', 329 | indigo: '#4B0082', 330 | ivory: '#FFFFF0', 331 | khaki: '#F0E68C', 332 | lavender: '#E6E6FA', 333 | lavenderblush: '#FFF0F5', 334 | lawngreen: '#7CFC00', 335 | lemonchiffon: '#FFFACD', 336 | lightblue: '#ADD8E6', 337 | lightcoral: '#F08080', 338 | lightcyan: '#E0FFFF', 339 | lightgoldenrodyellow: '#FAFAD2', 340 | lightgreen: '#90EE90', 341 | lightgrey: '#D3D3D3', 342 | lightpink: '#FFB6C1', 343 | lightsalmon: '#FFA07A', 344 | lightseagreen: '#20B2AA', 345 | lightskyblue: '#87CEFA', 346 | lightslategray: '#778899', 347 | lightslategrey: '#778899', 348 | lightsteelblue: '#B0C4DE', 349 | lightyellow: '#FFFFE0', 350 | limegreen: '#32CD32', 351 | linen: '#FAF0E6', 352 | magenta: '#FF00FF', 353 | mediumaquamarine: '#66CDAA', 354 | mediumblue: '#0000CD', 355 | mediumorchid: '#BA55D3', 356 | mediumpurple: '#9370DB', 357 | mediumseagreen: '#3CB371', 358 | mediumslateblue: '#7B68EE', 359 | mediumspringgreen: '#00FA9A', 360 | mediumturquoise: '#48D1CC', 361 | mediumvioletred: '#C71585', 362 | midnightblue: '#191970', 363 | mintcream: '#F5FFFA', 364 | mistyrose: '#FFE4E1', 365 | moccasin: '#FFE4B5', 366 | navajowhite: '#FFDEAD', 367 | oldlace: '#FDF5E6', 368 | olivedrab: '#6B8E23', 369 | orange: '#FFA500', 370 | orangered: '#FF4500', 371 | orchid: '#DA70D6', 372 | palegoldenrod: '#EEE8AA', 373 | palegreen: '#98FB98', 374 | paleturquoise: '#AFEEEE', 375 | palevioletred: '#DB7093', 376 | papayawhip: '#FFEFD5', 377 | peachpuff: '#FFDAB9', 378 | peru: '#CD853F', 379 | pink: '#FFC0CB', 380 | plum: '#DDA0DD', 381 | powderblue: '#B0E0E6', 382 | rosybrown: '#BC8F8F', 383 | royalblue: '#4169E1', 384 | saddlebrown: '#8B4513', 385 | salmon: '#FA8072', 386 | sandybrown: '#F4A460', 387 | seagreen: '#2E8B57', 388 | seashell: '#FFF5EE', 389 | sienna: '#A0522D', 390 | skyblue: '#87CEEB', 391 | slateblue: '#6A5ACD', 392 | slategray: '#708090', 393 | slategrey: '#708090', 394 | snow: '#FFFAFA', 395 | springgreen: '#00FF7F', 396 | steelblue: '#4682B4', 397 | tan: '#D2B48C', 398 | thistle: '#D8BFD8', 399 | tomato: '#FF6347', 400 | turquoise: '#40E0D0', 401 | violet: '#EE82EE', 402 | wheat: '#F5DEB3', 403 | whitesmoke: '#F5F5F5', 404 | yellowgreen: '#9ACD32' 405 | }; 406 | 407 | 408 | function getRgbHslContent(styleString) 409 | { 410 | var start = styleString.indexOf('(', 3); 411 | var end = styleString.indexOf(')', start + 1); 412 | var parts = styleString.substring(start + 1, end).split(','); 413 | // add alpha if needed 414 | if (parts.length != 4 || styleString.charAt(3) != 'a') { 415 | parts[3] = 1; 416 | } 417 | return parts; 418 | } 419 | 420 | function percent(s) 421 | { 422 | return parseFloat(s) / 100; 423 | } 424 | 425 | function clamp(v, min, max) 426 | { 427 | return Math.min(max, Math.max(min, v)); 428 | } 429 | 430 | function hslToRgb(parts) 431 | { 432 | var r, g, b, h, s, l; 433 | h = parseFloat(parts[0]) / 360 % 360; 434 | if (h < 0) 435 | h++; 436 | s = clamp(percent(parts[1]), 0, 1); 437 | l = clamp(percent(parts[2]), 0, 1); 438 | if (s == 0) { 439 | r = g = b = l; // achromatic 440 | } else { 441 | var q = l < 0.5 ? l * (1 + s) : l + s - l * s; 442 | var p = 2 * l - q; 443 | r = hueToRgb(p, q, h + 1 / 3); 444 | g = hueToRgb(p, q, h); 445 | b = hueToRgb(p, q, h - 1 / 3); 446 | } 447 | 448 | return '#' + decToHex[Math.floor(r * 255)] + 449 | decToHex[Math.floor(g * 255)] + 450 | decToHex[Math.floor(b * 255)]; 451 | } 452 | 453 | function hueToRgb(m1, m2, h) 454 | { 455 | if (h < 0) 456 | h++; 457 | if (h > 1) 458 | h--; 459 | 460 | if (6 * h < 1) 461 | return m1 + (m2 - m1) * 6 * h; 462 | else if (2 * h < 1) 463 | return m2; 464 | else if (3 * h < 2) 465 | return m1 + (m2 - m1) * (2 / 3 - h) * 6; 466 | else 467 | return m1; 468 | } 469 | 470 | var processStyleCache = {}; 471 | 472 | function processStyle(styleString) 473 | { 474 | if (styleString in processStyleCache) { 475 | return processStyleCache[styleString]; 476 | } 477 | 478 | var str, alpha = 1; 479 | 480 | styleString = String(styleString); 481 | if (styleString.charAt(0) == '#') { 482 | str = styleString; 483 | } else if (/^rgb/.test(styleString)) { 484 | var parts = getRgbHslContent(styleString); 485 | var str = '#', n; 486 | for (var i = 0; i < 3; i++) { 487 | if (parts[i].indexOf('%') != -1) { 488 | n = Math.floor(percent(parts[i]) * 255); 489 | } else { 490 | n = +parts[i]; 491 | } 492 | str += decToHex[clamp(n, 0, 255)]; 493 | } 494 | alpha = +parts[3]; 495 | } else if (/^hsl/.test(styleString)) { 496 | var parts = getRgbHslContent(styleString); 497 | str = hslToRgb(parts); 498 | alpha = parts[3]; 499 | } else { 500 | str = colorData[styleString] || styleString; 501 | } 502 | return processStyleCache[styleString] = { color: str, alpha: alpha }; 503 | } 504 | 505 | var DEFAULT_STYLE = { 506 | style: 'normal', 507 | variant: 'normal', 508 | weight: 'normal', 509 | size: 10, 510 | family: 'sans-serif' 511 | }; 512 | 513 | // Internal text style cache 514 | var fontStyleCache = {}; 515 | 516 | function processFontStyle(styleString) 517 | { 518 | if (fontStyleCache[styleString]) { 519 | return fontStyleCache[styleString]; 520 | } 521 | 522 | var el = document.createElement('div'); 523 | var style = el.style; 524 | try { 525 | style.font = styleString; 526 | } catch (ex) { 527 | // Ignore failures to set to invalid font. 528 | } 529 | 530 | return fontStyleCache[styleString] = { 531 | style: style.fontStyle || DEFAULT_STYLE.style, 532 | variant: style.fontVariant || DEFAULT_STYLE.variant, 533 | weight: style.fontWeight || DEFAULT_STYLE.weight, 534 | size: style.fontSize || DEFAULT_STYLE.size, 535 | family: style.fontFamily || DEFAULT_STYLE.family 536 | }; 537 | } 538 | 539 | function getComputedStyle(style, element) 540 | { 541 | var computedStyle = {}; 542 | 543 | for (var p in style) { 544 | computedStyle[p] = style[p]; 545 | } 546 | 547 | // Compute the size 548 | var canvasFontSize = parseFloat(element.currentStyle.fontSize), 549 | fontSize = parseFloat(style.size); 550 | 551 | if (typeof style.size == 'number') { 552 | computedStyle.size = style.size; 553 | } else if (style.size.indexOf('px') != -1) { 554 | computedStyle.size = fontSize; 555 | } else if (style.size.indexOf('em') != -1) { 556 | computedStyle.size = canvasFontSize * fontSize; 557 | } else if (style.size.indexOf('%') != -1) { 558 | computedStyle.size = (canvasFontSize / 100) * fontSize; 559 | } else if (style.size.indexOf('pt') != -1) { 560 | computedStyle.size = fontSize / .75; 561 | } else { 562 | computedStyle.size = canvasFontSize; 563 | } 564 | 565 | // Different scaling between normal text and VML text. This was found using 566 | // trial and error to get the same size as non VML text. 567 | computedStyle.size *= 0.981; 568 | 569 | return computedStyle; 570 | } 571 | 572 | function buildStyle(style) 573 | { 574 | return style.style + ' ' + style.variant + ' ' + style.weight + ' ' + 575 | style.size + 'px ' + style.family; 576 | } 577 | 578 | var lineCapMap = { 579 | 'butt': 'flat', 580 | 'round': 'round' 581 | }; 582 | 583 | function processLineCap(lineCap) 584 | { 585 | return lineCapMap[lineCap] || 'square'; 586 | } 587 | 588 | /** 589 | * This class implements CanvasRenderingContext2D interface as described by 590 | * the WHATWG. 591 | * @param {HTMLElement} canvasElement The element that the 2D context should 592 | * be associated with 593 | */ 594 | function CanvasRenderingContext2D_(canvasElement) 595 | { 596 | this.m_ = createMatrixIdentity(); 597 | 598 | this.mStack_ = []; 599 | this.aStack_ = []; 600 | this.currentPath_ = []; 601 | 602 | // Canvas context properties 603 | this.strokeStyle = '#000'; 604 | this.fillStyle = '#000'; 605 | 606 | this.lineWidth = 1; 607 | this.lineJoin = 'miter'; 608 | this.lineCap = 'butt'; 609 | this.miterLimit = Z * 1; 610 | this.globalAlpha = 1; 611 | this.font = '10px sans-serif'; 612 | this.textAlign = 'left'; 613 | this.textBaseline = 'alphabetic'; 614 | this.canvas = canvasElement; 615 | 616 | var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' + 617 | canvasElement.clientHeight + 'px;overflow:hidden;position:absolute'; 618 | var el = canvasElement.ownerDocument.createElement('div'); 619 | el.style.cssText = cssText; 620 | canvasElement.appendChild(el); 621 | 622 | var overlayEl = el.cloneNode(false); 623 | // Use a non transparent background. 624 | overlayEl.style.backgroundColor = 'red'; 625 | overlayEl.style.filter = 'alpha(opacity=0)'; 626 | canvasElement.appendChild(overlayEl); 627 | 628 | this.element_ = el; 629 | this.arcScaleX_ = 1; 630 | this.arcScaleY_ = 1; 631 | this.lineScale_ = 1; 632 | } 633 | 634 | var contextPrototype = CanvasRenderingContext2D_.prototype; 635 | contextPrototype.clearRect = function () 636 | { 637 | if (this.textMeasureEl_) { 638 | this.textMeasureEl_.removeNode(true); 639 | this.textMeasureEl_ = null; 640 | } 641 | this.element_.innerHTML = ''; 642 | }; 643 | 644 | contextPrototype.beginPath = function () 645 | { 646 | // TODO: Branch current matrix so that save/restore has no effect 647 | // as per safari docs. 648 | this.currentPath_ = []; 649 | }; 650 | 651 | contextPrototype.moveTo = function (aX, aY) 652 | { 653 | var p = getCoords(this, aX, aY); 654 | this.currentPath_.push({ type: 'moveTo', x: p.x, y: p.y }); 655 | this.currentX_ = p.x; 656 | this.currentY_ = p.y; 657 | }; 658 | 659 | contextPrototype.lineTo = function (aX, aY) 660 | { 661 | var p = getCoords(this, aX, aY); 662 | this.currentPath_.push({ type: 'lineTo', x: p.x, y: p.y }); 663 | 664 | this.currentX_ = p.x; 665 | this.currentY_ = p.y; 666 | }; 667 | 668 | contextPrototype.bezierCurveTo = function (aCP1x, aCP1y, 669 | aCP2x, aCP2y, 670 | aX, aY) 671 | { 672 | var p = getCoords(this, aX, aY); 673 | var cp1 = getCoords(this, aCP1x, aCP1y); 674 | var cp2 = getCoords(this, aCP2x, aCP2y); 675 | bezierCurveTo(this, cp1, cp2, p); 676 | }; 677 | 678 | // Helper function that takes the already fixed cordinates. 679 | function bezierCurveTo(self, cp1, cp2, p) 680 | { 681 | self.currentPath_.push({ 682 | type: 'bezierCurveTo', 683 | cp1x: cp1.x, 684 | cp1y: cp1.y, 685 | cp2x: cp2.x, 686 | cp2y: cp2.y, 687 | x: p.x, 688 | y: p.y 689 | }); 690 | self.currentX_ = p.x; 691 | self.currentY_ = p.y; 692 | } 693 | 694 | contextPrototype.quadraticCurveTo = function (aCPx, aCPy, aX, aY) 695 | { 696 | // the following is lifted almost directly from 697 | // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes 698 | 699 | var cp = getCoords(this, aCPx, aCPy); 700 | var p = getCoords(this, aX, aY); 701 | 702 | var cp1 = { 703 | x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), 704 | y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) 705 | }; 706 | var cp2 = { 707 | x: cp1.x + (p.x - this.currentX_) / 3.0, 708 | y: cp1.y + (p.y - this.currentY_) / 3.0 709 | }; 710 | 711 | bezierCurveTo(this, cp1, cp2, p); 712 | }; 713 | 714 | contextPrototype.arc = function (aX, aY, aRadius, 715 | aStartAngle, aEndAngle, aClockwise) 716 | { 717 | aRadius *= Z; 718 | var arcType = aClockwise ? 'at' : 'wa'; 719 | 720 | var xStart = aX + mc(aStartAngle) * aRadius - Z2; 721 | var yStart = aY + ms(aStartAngle) * aRadius - Z2; 722 | 723 | var xEnd = aX + mc(aEndAngle) * aRadius - Z2; 724 | var yEnd = aY + ms(aEndAngle) * aRadius - Z2; 725 | 726 | // IE won't render arches drawn counter clockwise if xStart == xEnd. 727 | if (xStart == xEnd && !aClockwise) { 728 | xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something 729 | // that can be represented in binary 730 | } 731 | 732 | var p = getCoords(this, aX, aY); 733 | var pStart = getCoords(this, xStart, yStart); 734 | var pEnd = getCoords(this, xEnd, yEnd); 735 | 736 | this.currentPath_.push({ type: arcType, 737 | x: p.x, 738 | y: p.y, 739 | radius: aRadius, 740 | xStart: pStart.x, 741 | yStart: pStart.y, 742 | xEnd: pEnd.x, 743 | yEnd: pEnd.y 744 | }); 745 | 746 | }; 747 | 748 | contextPrototype.rect = function (aX, aY, aWidth, aHeight) 749 | { 750 | this.moveTo(aX, aY); 751 | this.lineTo(aX + aWidth, aY); 752 | this.lineTo(aX + aWidth, aY + aHeight); 753 | this.lineTo(aX, aY + aHeight); 754 | this.closePath(); 755 | }; 756 | 757 | contextPrototype.strokeRect = function (aX, aY, aWidth, aHeight) 758 | { 759 | var oldPath = this.currentPath_; 760 | this.beginPath(); 761 | 762 | this.moveTo(aX, aY); 763 | this.lineTo(aX + aWidth, aY); 764 | this.lineTo(aX + aWidth, aY + aHeight); 765 | this.lineTo(aX, aY + aHeight); 766 | this.closePath(); 767 | this.stroke(); 768 | 769 | this.currentPath_ = oldPath; 770 | }; 771 | 772 | contextPrototype.fillRect = function (aX, aY, aWidth, aHeight) 773 | { 774 | var oldPath = this.currentPath_; 775 | this.beginPath(); 776 | 777 | this.moveTo(aX, aY); 778 | this.lineTo(aX + aWidth, aY); 779 | this.lineTo(aX + aWidth, aY + aHeight); 780 | this.lineTo(aX, aY + aHeight); 781 | this.closePath(); 782 | this.fill(); 783 | 784 | this.currentPath_ = oldPath; 785 | }; 786 | 787 | contextPrototype.createLinearGradient = function (aX0, aY0, aX1, aY1) 788 | { 789 | var gradient = new CanvasGradient_('gradient'); 790 | gradient.x0_ = aX0; 791 | gradient.y0_ = aY0; 792 | gradient.x1_ = aX1; 793 | gradient.y1_ = aY1; 794 | return gradient; 795 | }; 796 | 797 | contextPrototype.createRadialGradient = function (aX0, aY0, aR0, 798 | aX1, aY1, aR1) 799 | { 800 | var gradient = new CanvasGradient_('gradientradial'); 801 | gradient.x0_ = aX0; 802 | gradient.y0_ = aY0; 803 | gradient.r0_ = aR0; 804 | gradient.x1_ = aX1; 805 | gradient.y1_ = aY1; 806 | gradient.r1_ = aR1; 807 | return gradient; 808 | }; 809 | 810 | contextPrototype.drawImage = function (image, var_args) 811 | { 812 | var dx, dy, dw, dh, sx, sy, sw, sh; 813 | 814 | // to find the original width we overide the width and height 815 | var oldRuntimeWidth = image.runtimeStyle.width; 816 | var oldRuntimeHeight = image.runtimeStyle.height; 817 | image.runtimeStyle.width = 'auto'; 818 | image.runtimeStyle.height = 'auto'; 819 | 820 | // get the original size 821 | var w = image.width; 822 | var h = image.height; 823 | 824 | // and remove overides 825 | image.runtimeStyle.width = oldRuntimeWidth; 826 | image.runtimeStyle.height = oldRuntimeHeight; 827 | 828 | if (arguments.length == 3) { 829 | dx = arguments[1]; 830 | dy = arguments[2]; 831 | sx = sy = 0; 832 | sw = dw = w; 833 | sh = dh = h; 834 | } else if (arguments.length == 5) { 835 | dx = arguments[1]; 836 | dy = arguments[2]; 837 | dw = arguments[3]; 838 | dh = arguments[4]; 839 | sx = sy = 0; 840 | sw = w; 841 | sh = h; 842 | } else if (arguments.length == 9) { 843 | sx = arguments[1]; 844 | sy = arguments[2]; 845 | sw = arguments[3]; 846 | sh = arguments[4]; 847 | dx = arguments[5]; 848 | dy = arguments[6]; 849 | dw = arguments[7]; 850 | dh = arguments[8]; 851 | } else { 852 | throw Error('Invalid number of arguments'); 853 | } 854 | 855 | var d = getCoords(this, dx, dy); 856 | 857 | var w2 = sw / 2; 858 | var h2 = sh / 2; 859 | 860 | var vmlStr = []; 861 | 862 | var W = 10; 863 | var H = 10; 864 | 865 | // For some reason that I've now forgotten, using divs didn't work 866 | vmlStr.push(' ', 907 | '', 915 | ''); 916 | 917 | this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join('')); 918 | }; 919 | 920 | contextPrototype.stroke = function (aFill) 921 | { 922 | var lineStr = []; 923 | var lineOpen = false; 924 | 925 | var W = 10; 926 | var H = 10; 927 | 928 | lineStr.push(''); 996 | 997 | if (!aFill) { 998 | appendStroke(this, lineStr); 999 | } else { 1000 | appendFill(this, lineStr, min, max); 1001 | } 1002 | 1003 | lineStr.push(''); 1004 | 1005 | this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); 1006 | }; 1007 | 1008 | function appendStroke(ctx, lineStr) 1009 | { 1010 | var a = processStyle(ctx.strokeStyle); 1011 | var color = a.color; 1012 | var opacity = a.alpha * ctx.globalAlpha; 1013 | var lineWidth = ctx.lineScale_ * ctx.lineWidth; 1014 | 1015 | // VML cannot correctly render a line if the width is less than 1px. 1016 | // In that case, we dilute the color to make the line look thinner. 1017 | if (lineWidth < 1) { 1018 | opacity *= lineWidth; 1019 | } 1020 | 1021 | lineStr.push( 1022 | '' 1029 | ); 1030 | } 1031 | 1032 | function appendFill(ctx, lineStr, min, max) 1033 | { 1034 | var fillStyle = ctx.fillStyle; 1035 | var arcScaleX = ctx.arcScaleX_; 1036 | var arcScaleY = ctx.arcScaleY_; 1037 | var width = max.x - min.x; 1038 | var height = max.y - min.y; 1039 | if (fillStyle instanceof CanvasGradient_) { 1040 | // TODO: Gradients transformed with the transformation matrix. 1041 | var angle = 0; 1042 | var focus = { x: 0, y: 0 }; 1043 | 1044 | // additional offset 1045 | var shift = 0; 1046 | // scale factor for offset 1047 | var expansion = 1; 1048 | 1049 | if (fillStyle.type_ == 'gradient') { 1050 | var x0 = fillStyle.x0_ / arcScaleX; 1051 | var y0 = fillStyle.y0_ / arcScaleY; 1052 | var x1 = fillStyle.x1_ / arcScaleX; 1053 | var y1 = fillStyle.y1_ / arcScaleY; 1054 | var p0 = getCoords(ctx, x0, y0); 1055 | var p1 = getCoords(ctx, x1, y1); 1056 | var dx = p1.x - p0.x; 1057 | var dy = p1.y - p0.y; 1058 | angle = Math.atan2(dx, dy) * 180 / Math.PI; 1059 | 1060 | // The angle should be a non-negative number. 1061 | if (angle < 0) { 1062 | angle += 360; 1063 | } 1064 | 1065 | // Very small angles produce an unexpected result because they are 1066 | // converted to a scientific notation string. 1067 | if (angle < 1e-6) { 1068 | angle = 0; 1069 | } 1070 | } else { 1071 | var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_); 1072 | focus = { 1073 | x: (p0.x - min.x) / width, 1074 | y: (p0.y - min.y) / height 1075 | }; 1076 | 1077 | width /= arcScaleX * Z; 1078 | height /= arcScaleY * Z; 1079 | var dimension = m.max(width, height); 1080 | shift = 2 * fillStyle.r0_ / dimension; 1081 | expansion = 2 * fillStyle.r1_ / dimension - shift; 1082 | } 1083 | 1084 | // We need to sort the color stops in ascending order by offset, 1085 | // otherwise IE won't interpret it correctly. 1086 | var stops = fillStyle.colors_; 1087 | stops.sort(function (cs1, cs2) 1088 | { 1089 | return cs1.offset - cs2.offset; 1090 | }); 1091 | 1092 | var length = stops.length; 1093 | var color1 = stops[0].color; 1094 | var color2 = stops[length - 1].color; 1095 | var opacity1 = stops[0].alpha * ctx.globalAlpha; 1096 | var opacity2 = stops[length - 1].alpha * ctx.globalAlpha; 1097 | 1098 | var colors = []; 1099 | for (var i = 0; i < length; i++) { 1100 | var stop = stops[i]; 1101 | colors.push(stop.offset * expansion + shift + ' ' + stop.color); 1102 | } 1103 | 1104 | // When colors attribute is used, the meanings of opacity and o:opacity2 1105 | // are reversed. 1106 | lineStr.push(''); 1115 | } else if (fillStyle instanceof CanvasPattern_) { 1116 | if (width && height) { 1117 | var deltaLeft = -min.x; 1118 | var deltaTop = -min.y; 1119 | lineStr.push(''); 1127 | } 1128 | } else { 1129 | var a = processStyle(ctx.fillStyle); 1130 | var color = a.color; 1131 | var opacity = a.alpha * ctx.globalAlpha; 1132 | lineStr.push(''); 1134 | } 1135 | } 1136 | 1137 | contextPrototype.fill = function () 1138 | { 1139 | this.stroke(true); 1140 | }; 1141 | 1142 | contextPrototype.closePath = function () 1143 | { 1144 | this.currentPath_.push({ type: 'close' }); 1145 | }; 1146 | 1147 | function getCoords(ctx, aX, aY) 1148 | { 1149 | var m = ctx.m_; 1150 | return { 1151 | x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, 1152 | y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 1153 | }; 1154 | }; 1155 | 1156 | contextPrototype.save = function () 1157 | { 1158 | var o = {}; 1159 | copyState(this, o); 1160 | this.aStack_.push(o); 1161 | this.mStack_.push(this.m_); 1162 | this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); 1163 | }; 1164 | 1165 | contextPrototype.restore = function () 1166 | { 1167 | if (this.aStack_.length) { 1168 | copyState(this.aStack_.pop(), this); 1169 | this.m_ = this.mStack_.pop(); 1170 | } 1171 | }; 1172 | 1173 | function matrixIsFinite(m) 1174 | { 1175 | return isFinite(m[0][0]) && isFinite(m[0][1]) && 1176 | isFinite(m[1][0]) && isFinite(m[1][1]) && 1177 | isFinite(m[2][0]) && isFinite(m[2][1]); 1178 | } 1179 | 1180 | function setM(ctx, m, updateLineScale) 1181 | { 1182 | if (!matrixIsFinite(m)) { 1183 | return; 1184 | } 1185 | ctx.m_ = m; 1186 | 1187 | if (updateLineScale) { 1188 | // Get the line scale. 1189 | // Determinant of this.m_ means how much the area is enlarged by the 1190 | // transformation. So its square root can be used as a scale factor 1191 | // for width. 1192 | var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; 1193 | ctx.lineScale_ = sqrt(abs(det)); 1194 | } 1195 | } 1196 | 1197 | contextPrototype.translate = function (aX, aY) 1198 | { 1199 | var m1 = [ 1200 | [1, 0, 0], 1201 | [0, 1, 0], 1202 | [aX, aY, 1] 1203 | ]; 1204 | 1205 | setM(this, matrixMultiply(m1, this.m_), false); 1206 | }; 1207 | 1208 | contextPrototype.rotate = function (aRot) 1209 | { 1210 | var c = mc(aRot); 1211 | var s = ms(aRot); 1212 | 1213 | var m1 = [ 1214 | [c, s, 0], 1215 | [-s, c, 0], 1216 | [0, 0, 1] 1217 | ]; 1218 | 1219 | setM(this, matrixMultiply(m1, this.m_), false); 1220 | }; 1221 | 1222 | contextPrototype.scale = function (aX, aY) 1223 | { 1224 | this.arcScaleX_ *= aX; 1225 | this.arcScaleY_ *= aY; 1226 | var m1 = [ 1227 | [aX, 0, 0], 1228 | [0, aY, 0], 1229 | [0, 0, 1] 1230 | ]; 1231 | 1232 | setM(this, matrixMultiply(m1, this.m_), true); 1233 | }; 1234 | 1235 | contextPrototype.transform = function (m11, m12, m21, m22, dx, dy) 1236 | { 1237 | var m1 = [ 1238 | [m11, m12, 0], 1239 | [m21, m22, 0], 1240 | [dx, dy, 1] 1241 | ]; 1242 | 1243 | setM(this, matrixMultiply(m1, this.m_), true); 1244 | }; 1245 | 1246 | contextPrototype.setTransform = function (m11, m12, m21, m22, dx, dy) 1247 | { 1248 | var m = [ 1249 | [m11, m12, 0], 1250 | [m21, m22, 0], 1251 | [dx, dy, 1] 1252 | ]; 1253 | 1254 | setM(this, m, true); 1255 | }; 1256 | 1257 | /** 1258 | * The text drawing function. 1259 | * The maxWidth argument isn't taken in account, since no browser supports 1260 | * it yet. 1261 | */ 1262 | contextPrototype.drawText_ = function (text, x, y, maxWidth, stroke) 1263 | { 1264 | var m = this.m_, 1265 | delta = 1000, 1266 | left = 0, 1267 | right = delta, 1268 | offset = { x: 0, y: 0 }, 1269 | lineStr = []; 1270 | 1271 | var fontStyle = getComputedStyle(processFontStyle(this.font), 1272 | this.element_); 1273 | 1274 | var fontStyleString = buildStyle(fontStyle); 1275 | 1276 | var elementStyle = this.element_.currentStyle; 1277 | var textAlign = this.textAlign.toLowerCase(); 1278 | switch (textAlign) { 1279 | case 'left': 1280 | case 'center': 1281 | case 'right': 1282 | break; 1283 | case 'end': 1284 | textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left'; 1285 | break; 1286 | case 'start': 1287 | textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left'; 1288 | break; 1289 | default: 1290 | textAlign = 'left'; 1291 | } 1292 | 1293 | // 1.75 is an arbitrary number, as there is no info about the text baseline 1294 | switch (this.textBaseline) { 1295 | case 'hanging': 1296 | case 'top': 1297 | offset.y = fontStyle.size / 1.75; 1298 | break; 1299 | case 'middle': 1300 | break; 1301 | default: 1302 | case null: 1303 | case 'alphabetic': 1304 | case 'ideographic': 1305 | case 'bottom': 1306 | offset.y = -fontStyle.size / 2.25; 1307 | break; 1308 | } 1309 | 1310 | switch (textAlign) { 1311 | case 'right': 1312 | left = delta; 1313 | right = 0.05; 1314 | break; 1315 | case 'center': 1316 | left = right = delta / 2; 1317 | break; 1318 | } 1319 | 1320 | var d = getCoords(this, x + offset.x, y + offset.y); 1321 | 1322 | lineStr.push(''); 1326 | 1327 | if (stroke) { 1328 | appendStroke(this, lineStr); 1329 | } else { 1330 | // TODO: Fix the min and max params. 1331 | appendFill(this, lineStr, { x: -left, y: 0 }, 1332 | { x: right, y: fontStyle.size }); 1333 | } 1334 | 1335 | var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' + 1336 | m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0'; 1337 | 1338 | var skewOffset = mr(d.x / Z) + ',' + mr(d.y / Z); 1339 | 1340 | lineStr.push('', 1342 | '', 1343 | ''); 1348 | 1349 | this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); 1350 | }; 1351 | 1352 | contextPrototype.fillText = function (text, x, y, maxWidth) 1353 | { 1354 | this.drawText_(text, x, y, maxWidth, false); 1355 | }; 1356 | 1357 | contextPrototype.strokeText = function (text, x, y, maxWidth) 1358 | { 1359 | this.drawText_(text, x, y, maxWidth, true); 1360 | }; 1361 | 1362 | contextPrototype.measureText = function (text) 1363 | { 1364 | if (!this.textMeasureEl_) { 1365 | var s = ''; 1368 | this.element_.insertAdjacentHTML('beforeEnd', s); 1369 | this.textMeasureEl_ = this.element_.lastChild; 1370 | } 1371 | var doc = this.element_.ownerDocument; 1372 | this.textMeasureEl_.innerHTML = ''; 1373 | this.textMeasureEl_.style.font = this.font; 1374 | // Don't use innerHTML or innerText because they allow markup/whitespace. 1375 | this.textMeasureEl_.appendChild(doc.createTextNode(text)); 1376 | return { width: this.textMeasureEl_.offsetWidth }; 1377 | }; 1378 | 1379 | /******** STUBS ********/ 1380 | contextPrototype.clip = function () 1381 | { 1382 | // TODO: Implement 1383 | }; 1384 | 1385 | contextPrototype.arcTo = function () 1386 | { 1387 | // TODO: Implement 1388 | }; 1389 | 1390 | contextPrototype.createPattern = function (image, repetition) 1391 | { 1392 | return new CanvasPattern_(image, repetition); 1393 | }; 1394 | 1395 | // Gradient / Pattern Stubs 1396 | function CanvasGradient_(aType) 1397 | { 1398 | this.type_ = aType; 1399 | this.x0_ = 0; 1400 | this.y0_ = 0; 1401 | this.r0_ = 0; 1402 | this.x1_ = 0; 1403 | this.y1_ = 0; 1404 | this.r1_ = 0; 1405 | this.colors_ = []; 1406 | } 1407 | 1408 | CanvasGradient_.prototype.addColorStop = function (aOffset, aColor) 1409 | { 1410 | aColor = processStyle(aColor); 1411 | this.colors_.push({ offset: aOffset, 1412 | color: aColor.color, 1413 | alpha: aColor.alpha 1414 | }); 1415 | }; 1416 | 1417 | function CanvasPattern_(image, repetition) 1418 | { 1419 | assertImageIsValid(image); 1420 | switch (repetition) { 1421 | case 'repeat': 1422 | case null: 1423 | case '': 1424 | this.repetition_ = 'repeat'; 1425 | break 1426 | case 'repeat-x': 1427 | case 'repeat-y': 1428 | case 'no-repeat': 1429 | this.repetition_ = repetition; 1430 | break; 1431 | default: 1432 | throwException('SYNTAX_ERR'); 1433 | } 1434 | 1435 | this.src_ = image.src; 1436 | this.width_ = image.width; 1437 | this.height_ = image.height; 1438 | } 1439 | 1440 | function throwException(s) 1441 | { 1442 | throw new DOMException_(s); 1443 | } 1444 | 1445 | function assertImageIsValid(img) 1446 | { 1447 | if (!img || img.nodeType != 1 || img.tagName != 'IMG') { 1448 | throwException('TYPE_MISMATCH_ERR'); 1449 | } 1450 | if (img.readyState != 'complete') { 1451 | throwException('INVALID_STATE_ERR'); 1452 | } 1453 | } 1454 | 1455 | function DOMException_(s) 1456 | { 1457 | this.code = this[s]; 1458 | this.message = s + ': DOM Exception ' + this.code; 1459 | } 1460 | var p = DOMException_.prototype = new Error; 1461 | p.INDEX_SIZE_ERR = 1; 1462 | p.DOMSTRING_SIZE_ERR = 2; 1463 | p.HIERARCHY_REQUEST_ERR = 3; 1464 | p.WRONG_DOCUMENT_ERR = 4; 1465 | p.INVALID_CHARACTER_ERR = 5; 1466 | p.NO_DATA_ALLOWED_ERR = 6; 1467 | p.NO_MODIFICATION_ALLOWED_ERR = 7; 1468 | p.NOT_FOUND_ERR = 8; 1469 | p.NOT_SUPPORTED_ERR = 9; 1470 | p.INUSE_ATTRIBUTE_ERR = 10; 1471 | p.INVALID_STATE_ERR = 11; 1472 | p.SYNTAX_ERR = 12; 1473 | p.INVALID_MODIFICATION_ERR = 13; 1474 | p.NAMESPACE_ERR = 14; 1475 | p.INVALID_ACCESS_ERR = 15; 1476 | p.VALIDATION_ERR = 16; 1477 | p.TYPE_MISMATCH_ERR = 17; 1478 | 1479 | // set up externs 1480 | G_vmlCanvasManager = G_vmlCanvasManager_; 1481 | CanvasRenderingContext2D = CanvasRenderingContext2D_; 1482 | CanvasGradient = CanvasGradient_; 1483 | CanvasPattern = CanvasPattern_; 1484 | DOMException = DOMException_; 1485 | })(); 1486 | 1487 | } // if 1488 | -------------------------------------------------------------------------------- /js/jquery-1.7.2.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtimus/GoxTradingBot/85a67d27b856949cf27440ae77a56d4a83e0bfbe/js/jquery-1.7.2.min.js -------------------------------------------------------------------------------- /js/jquery.jqRangeSlider.min.js: -------------------------------------------------------------------------------- 1 | (function(a){a.fn.jqRangeSlider=function(c,e,f){if(typeof c==="object")e=c;else if(typeof c==="string"){c=c.toLowerCase();if(a.fn.jqRangeSlider.methods[c])return a.fn.jqRangeSlider.methods[c].call(this,e,f);else a.error("Method "+method+" does not exist on jQuery.jqRangeSlider")}var d=this.data("data");if(!d){d=new b(this);this.data("data",d)}d._setOptions(e);return this};a.fn.jqRangeSlider.methods={rangeslider:function(){return this.data("data")},destroy:function(){var a=this.data("data");if(a){a.destroy();this.removeData("data")}},options:function(){var a=this.data("data");return!a?void 0:a.options},option:function(b,c){var a=this.data("data");if(!a)return;if(!c)return a.options[b];a.options[b]=c;a._setOptions(a.options)},update:function(c){var b=this.data("data");if(!b)return this;var d=a.extend(false,{},b.options,c||{});b._setOptions(d);return this},preview:function(){var a=this.data("data");return a?a.orientation=="horizontal"?a.bgHor:a.bgVer:null}};a.fn.jqRangeSlider.defaults={orientation:"horizontal",mode:"normal",minimum:0,maximum:100,minRange:0,range:{minimum:null,maximum:null},smallChange:10,largeChange:20,reversed:false};a.fn.jqMouseCapture=function(b){var c=a(document);this.each(function(){var d=a(this),e={};d.mousedown(function(h){var f;if(b.move){f=function(a){b.move.call(d,a,e)};c.mousemove(f)}var a,g=function(){b.move&&c.unbind("mousemove",f);c.unbind("mouseup",a)};if(b.up)a=function(a){g();return b.up.call(d,a,e)};else a=g;c.mouseup(a);h.preventDefault();return b.down.call(d,h,e)})});return this};var c=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){return window.setTimeout(function(){a()},25)}}();function d(f){var d=f,a=false,b=false;function e(){if(a){d();c(e);b=true;a=false}else b=false}this.kick=function(){a=true;!b&&e()};this.end=function(c){var e=d;if(!c)return;if(!b)c();else{d=a?function(){e();c()}:c;a=true}}}function b(b){this._init(b);this.isTouchDevice=!!("ontouchstart"in window);this.timer=new d(a.proxy(this._arrangeElements,this))}b.prototype={_init:function(a){this.elem=a;a.addClass("ui-jqrangeslider ui-widget");a.css("position")=="static"&&a.css("position","relative")},_createElements:function(){var a=this.elem;a.children().remove();if(this.orientation=="horizontal")this._createHorElements(a);else this._createVerElements(a)},_createHorElements:function(c){var b=this;this.bgHor=a("
").css("top",0).css("left",0);c.append(this.bgHor);this.bgHorLeft=a("
").css("top",0).css("left",0).jqMouseCapture({down:function(a){b._largeScrollStart(a);b.scrolling=true;b.scrollingCount=0;b._scrollLeft()},up:a.proxy(b._stopScroll,this)});c.append(this.bgHorLeft);this.bgHorRight=a("
").css("top",0).css("left",0).jqMouseCapture({down:function(a){b._largeScrollStart(a);b.scrolling=true;b.scrollingCount=0;b._scrollRight()},up:a.proxy(b._stopScroll,this)});c.append(this.bgHorRight);this.arrowLeft=a("
").css("top",0).css("left",0).jqMouseCapture({down:function(){b.scrolling=true;b.scrollingCount=0;b._scrollLeft()},up:a.proxy(b._stopScroll,this)});c.append(this.arrowLeft);this._addHover(this.arrowLeft);this.arrowIconLeft=a("");this.arrowLeft.append(this.arrowIconLeft);this.arrowRight=a("
").css("top",0).css("left",0).jqMouseCapture({down:function(){b.scrolling=true;b.scrollingCount=0;b._scrollRight()},up:a.proxy(b._stopScroll,this)});c.append(this.arrowRight);this._addHover(this.arrowRight);this.arrowIconRight=a("");this.arrowRight.append(this.arrowIconRight);this.sliderHor=a("
").css("top",0).css("left",0).jqMouseCapture({down:a.proxy(b._startDragHor,this),move:a.proxy(b._draggingHor,this),up:a.proxy(b._stopDragHor,this)});c.append(this.sliderHor);this.handleLeft=a("
").css("top",0).css("left",0).jqMouseCapture({down:a.proxy(b._startResizeLeft,this),move:a.proxy(b._resizeLeft,this),up:a.proxy(b._stopResizeLeft,this)});c.append(this.handleLeft);this._addHover(this.handleLeft);this.handleIconLeft=a("");this.handleLeft.append(this.handleIconLeft);this.handleRight=a("
").css("top",0).css("left",0).jqMouseCapture({down:a.proxy(b._startResizeRight,this),move:a.proxy(b._resizeRight,this),up:a.proxy(b._stopResizeRight,this)});c.append(this.handleRight);this._addHover(this.handleRight);this.handleIconRight=a("");this.handleRight.append(this.handleIconRight);if(this.mode!="preview"){this.bgHorLeft.addClass("ui-widget-content");this.bgHorRight.addClass("ui-widget-content");this.sliderHor.addClass("ui-widget-header")}if(this.isTouchDevice){this.bgHorLeft.bind("touchstart",function(a){a.preventDefault();b._largeScrollStart(a,true);b.scrolling=true;b.scrollingCount=0;b._scrollLeft()}).bind("touchend",function(){b._stopScroll()});this.bgHorRight.bind("touchstart",function(a){a.preventDefault();b._largeScrollStart(a,true);b.scrolling=true;b.scrollingCount=0;b._scrollRight()}).bind("touchend",function(){b._stopScroll()});this.arrowLeft.bind("touchstart",function(a){a.preventDefault();b.scrolling=true;b.scrollingCount=0;b._scrollLeft()}).bind("touchend",function(){b._stopScroll()});this.arrowRight.bind("touchstart",function(a){a.preventDefault();b.scrolling=true;b.scrollingCount=0;b._scrollRight()}).bind("touchend",function(){b._stopScroll()});this.sliderHor.bind("touchstart",function(a){b._startDragHor(a,true)}).bind("touchmove",function(a){b._draggingHor(a,true)}).bind("touchend",function(a){b._stopDragHor(a)});this.handleLeft.bind("touchstart",function(a){b._startResizeLeft(a,true)}).bind("touchmove",function(a){b._resizeLeft(a,true)}).bind("touchend",function(a){b._stopResizeLeft(a)});this.handleRight.bind("touchstart",function(a){b._startResizeRight(a,true)}).bind("touchmove",function(a){b._resizeRight(a,true)}).bind("touchend",function(a){b._stopResizeRight(a)})}},_createVerElements:function(c){var b=this;this.bgVer=a("
").css("top",0).css("left",0);c.append(this.bgVer);this.bgVerBottom=a("
").css("top",0).css("left",0).jqMouseCapture({down:function(a){b._largeScrollStart(a);b.scrolling=true;b.scrollingCount=0;b._scrollLeft()},up:a.proxy(b._stopScroll,this)});c.append(this.bgVerBottom);this.bgVerTop=a("
").css("top",0).css("left",0).jqMouseCapture({down:function(a){b._largeScrollStart(a);b.scrolling=true;b.scrollingCount=0;b._scrollRight()},up:a.proxy(b._stopScroll,this)});c.append(this.bgVerTop);this.arrowBottom=a("
").css("top",0).css("left",0).jqMouseCapture({down:function(){b.scrolling=true;b.scrollingCount=0;b._scrollLeft()},up:a.proxy(b._stopScroll,this)});c.append(this.arrowBottom);this._addHover(this.arrowBottom);this.arrowIconBottom=a("");this.arrowBottom.append(this.arrowIconBottom);this.arrowTop=a("
").css("top",0).css("left",0).jqMouseCapture({down:function(){b.scrolling=true;b.scrollingCount=0;b._scrollRight()},up:a.proxy(b._stopScroll,this)});c.append(this.arrowTop);this._addHover(this.arrowTop);this.arrowIconTop=a("");this.arrowTop.append(this.arrowIconTop);this.sliderVer=a("
").css("top",0).css("left",0).jqMouseCapture({down:a.proxy(b._startDragVer,this),move:a.proxy(b._draggingVer,this),up:a.proxy(b._stopDragVer,this)});c.append(this.sliderVer);this.handleBottom=a("
").css("top",0).css("left",0).jqMouseCapture({down:a.proxy(b._startResizeBottom,this),move:a.proxy(b._resizeBottom,this),up:a.proxy(b._stopResizeBottom,this)});c.append(this.handleBottom);this._addHover(this.handleBottom);this.handleIconBottom=a("");this.handleBottom.append(this.handleIconBottom);this.handleTop=a("
").css("top",0).css("left",0).jqMouseCapture({down:a.proxy(b._startResizeTop,this),move:a.proxy(b._resizeTop,this),up:a.proxy(b._stopResizeTop,this)});c.append(this.handleTop);this._addHover(this.handleTop);this.handleIconTop=a("");this.handleTop.append(this.handleIconTop);if(this.mode!="preview"){this.bgVerBottom.addClass("ui-widget-content");this.bgVerTop.addClass("ui-widget-content");this.sliderVer.addClass("ui-widget-header")}if(this.isTouchDevice){this.bgVerBottom.bind("touchstart",function(a){a.preventDefault();b._largeScrollStart(a,true);b.scrolling=true;b.scrollingCount=0;b._scrollLeft()}).bind("touchend",function(){b._stopScroll()});this.bgVerTop.bind("touchstart",function(a){a.preventDefault();b._largeScrollStart(a,true);b.scrolling=true;b.scrollingCount=0;b._scrollRight()}).bind("touchend",function(){b._stopScroll()});this.arrowBottom.bind("touchstart",function(a){a.preventDefault();b.scrolling=true;b.scrollingCount=0;b._scrollLeft()}).bind("touchend",function(){b._stopScroll()});this.arrowTop.bind("touchstart",function(a){a.preventDefault();b.scrolling=true;b.scrollingCount=0;b._scrollRight()}).bind("touchend",function(){b._stopScroll()});this.sliderVer.bind("touchstart",function(a){b._startDragVer(a,true)}).bind("touchmove",function(a){b._draggingVer(a,true)}).bind("touchend",function(a){b._stopDragVer(a)});this.handleBottom.bind("touchstart",function(a){b._startResizeBottom(a,true)}).bind("touchmove",function(a){b._resizeBottom(a,true)}).bind("touchend",function(a){b._stopResizeBottom(a)});this.handleTop.bind("touchstart",function(a){b._startResizeTop(a,true)}).bind("touchmove",function(a){b._resizeTop(a,true)}).bind("touchend",function(a){b._stopResizeTop(a)})}},_setOptions:function(d){var b=a.extend(true,{},a.fn.jqRangeSlider.defaults,d||{});this.options=b;if(!b.range)b.range={};if(this.orientation!=b.orientation||this.mode!=b.mode){this.orientation=b.orientation;this.mode=b.mode;this._createElements()}var c=b.range;c.minimum=c.minimum===null||c.minimum===undefined?b.minimum:c.minimum;c.maximum=c.maximum===null||c.maximum===undefined?b.maximum:c.maximum;this.lastChange=a.extend({},c);this._arrange()},_arrange:function(){this.timer.kick()},_arrangeElements:function(){if(this.orientation=="horizontal")this._arrangeHor();else this._arrangeVer()},_arrangeHor:function(){var k=this.options,l=k.range,m=this.elem,i=m.width(),c=m.height(),g=this.arrowLeft.outerWidth(),f=this.arrowRight.outerWidth(),d=this.handleLeft.outerWidth(),j=this.handleRight.outerWidth();this._outerH(this.arrowLeft,c);this._outerH(this.arrowRight,c).css("left",i-f);this.arrowIconLeft.css({top:(this.arrowLeft.height()-this.arrowIconLeft.height())/2,left:(this.arrowLeft.width()-this.arrowIconLeft.width())/2});this.arrowIconRight.css({top:(this.arrowRight.height()-this.arrowIconRight.height())/2,left:(this.arrowRight.width()-this.arrowIconRight.width())/2});var a=g,b=i-a-f-d-j;this.innerW=b;this._outerH(this.bgHor,c).css("left",a+d);this._outerW(this.bgHor,b);var e=Math.round(this._map(l.minimum,b)),h=Math.round(b-this._map(l.maximum,b));if(k.reversed){var n=e;e=h;h=n}a+=e;b-=e+h;this._outerH(this.handleLeft,c).css("left",a);this._outerH(this.handleRight,c).css("left",a+b+d);this.handleIconLeft.css({top:(this.handleLeft.height()-this.handleIconLeft.height())/2,left:(this.handleLeft.width()-this.handleIconLeft.width())/2});this.handleIconRight.css({top:(this.handleRight.height()-this.handleIconRight.height())/2,left:(this.handleRight.width()-this.handleIconRight.width())/2});this._outerH(this.sliderHor,c).css("left",a+d);this._outerW(this.sliderHor,b);this._outerH(this.bgHorLeft,c).css("left",g);this._outerW(this.bgHorLeft,a-g);a+=b+d+j;this._outerH(this.bgHorRight,c).css("left",a);this._outerW(this.bgHorRight,i-a-f)},_arrangeVer:function(){var k=this.options,l=k.range,m=this.elem,c=m.width(),i=m.height(),f=this.arrowBottom.outerHeight(),g=this.arrowTop.outerHeight(),j=this.handleBottom.outerHeight(),d=this.handleTop.outerHeight();this._outerW(this.arrowBottom,c).css("top",i-f);this._outerW(this.arrowTop,c);this.arrowIconBottom.css({top:(this.arrowBottom.height()-this.arrowIconBottom.height())/2,left:(this.arrowBottom.width()-this.arrowIconBottom.width())/2});this.arrowIconTop.css({top:(this.arrowTop.height()-this.arrowIconTop.height())/2,left:(this.arrowTop.width()-this.arrowIconTop.width())/2});var a=g,b=i-a-f-j-d;this.innerH=b;this._outerW(this.bgVer,c).css("top",a+d);this._outerH(this.bgVer,b);var h=Math.round(this._map(l.minimum,b)),e=Math.round(b-this._map(l.maximum,b));if(k.reversed){var n=h;h=e;e=n}a+=e;b-=h+e;this._outerW(this.handleTop,c).css("top",a);this._outerW(this.handleBottom,c).css("top",a+b+d);this.handleIconBottom.css({top:(this.handleBottom.height()-this.handleIconBottom.height())/2,left:(this.handleBottom.width()-this.handleIconBottom.width())/2});this.handleIconTop.css({top:(this.handleTop.height()-this.handleIconTop.height())/2,left:(this.handleTop.width()-this.handleIconTop.width())/2});this._outerW(this.sliderVer,c).css("top",a+d);this._outerH(this.sliderVer,b);this._outerW(this.bgVerTop,c).css("top",g);this._outerH(this.bgVerTop,a-g);a+=b+j+d;this._outerW(this.bgVerBottom,c).css("top",a);this._outerH(this.bgVerBottom,i-a-f)},_map:function(f,c){var b=this.options,d=b.maximum-b.minimum,e=f-b.minimum,a=c*e/d;a=Math.min(a,c);a=Math.max(a,0);return a},_trigger:function(d,e){var b=this.options.range,c=this.lastChange;if(this.startMin===b.minimum&&this.startMax===b.maximum)return;if(!e&&c.minimum===b.minimum&&c.maximum===b.maximum)return;this.startMin=null;this.startMax=null;this.elem.trigger(d,{minimum:b.minimum,maximum:b.maximum});a.extend(c,b)},_startChange:function(){this.valueMin=this.startMin=this.options.range.minimum;this.valueMax=this.startMax=this.options.range.maximum},_largeScrollStart:function(c,h){if(h&&c.originalEvent.touches)c=c.originalEvent.touches[0];var i=c.pageX,j=c.pageY,e=this.elem.offset(),f=i-e.left,g=j-e.top,a=this.options,d=a.maximum-a.minimum,b;if(this.orientation=="horizontal"){f-=parseFloat(this.bgHor.css("left"));b=a.minimum+d*f/this.innerW}else{g-=parseFloat(this.bgVer.css("top"));b=a.maximum-d*g/this.innerH}if(a.reversed)b=a.minimum+a.maximum-b;this.endScrollValue=b},_moveLeft:function(){var a=this.options,d=a.range.maximum-a.range.minimum,b=a.range.minimum-a.smallChange;b=Math.max(a.minimum,b);var c=b+d;a.range.minimum=b;a.range.maximum=c;this._arrange();this._trigger("rangeChanged");if(this.endScrollValue)if((b+c)/2this.endScrollValue)return true;return false},_scrollLeft:function(){if(!this.scrolling)return;var b;if(!this.options.reversed)b=this._moveLeft();else b=this._moveRight();if(b){this.endScrollValue=null;return}var c=this.scrollingCount?100:200;this.scrollingCount++;setTimeout(a.proxy(this._scrollLeft,this),c)},_scrollRight:function(){if(!this.scrolling)return;var b;if(!this.options.reversed)b=this._moveRight();else b=this._moveLeft();if(b){this.endScrollValue=null;return}var c=this.scrollingCount?100:200;this.scrollingCount++;setTimeout(a.proxy(this._scrollRight,this),c)},_stopScroll:function(){this.scrolling=false},_startDragHor:function(a,b){a.preventDefault();if(b&&a.originalEvent.touches)a=a.originalEvent.touches[0];this.dragging=true;this.pos=a.pageX;this._startChange();this.sliderHor.addClass("ui-jqrangeslider-slider-horizontal-dragging")},_draggingHor:function(c,d){if(!this.dragging)return;c.preventDefault();if(d&&c.originalEvent.touches)c=c.originalEvent.touches[0];var f=c.pageX-this.pos,b=this.options,e=b.maximum-b.minimum,a=e*f/this.innerW;if(b.reversed)a=-a;a=Math.max(a,b.minimum-this.valueMin);a=Math.min(a,b.maximum-this.valueMax);b.range.minimum=this.valueMin+a;b.range.maximum=this.valueMax+a;this._arrange();this._trigger("rangeChanging")},_stopDragHor:function(a){a.preventDefault();this.dragging=false;this.sliderHor.removeClass("ui-jqrangeslider-slider-horizontal-dragging");this._trigger("rangeChanged",true);this.valueMin=null;this.valueMax=null},_startDragVer:function(a,b){a.preventDefault();if(b&&a.originalEvent.touches)a=a.originalEvent.touches[0];this.dragging=true;this.pos=a.pageY;this._startChange();this.sliderVer.addClass("ui-jqrangeslider-slider-vertical-dragging")},_draggingVer:function(c,d){if(!this.dragging)return;c.preventDefault();if(d&&c.originalEvent.touches)c=c.originalEvent.touches[0];var f=this.pos-c.pageY,b=this.options,e=b.maximum-b.minimum,a=e*f/this.innerH;if(b.reversed)a=-a;a=Math.max(a,b.minimum-this.valueMin);a=Math.min(a,b.maximum-this.valueMax);b.range.minimum=this.valueMin+a;b.range.maximum=this.valueMax+a;this._arrange();this._trigger("rangeChanging")},_stopDragVer:function(a){a.preventDefault();this.dragging=false;this.sliderVer.removeClass("ui-jqrangeslider-slider-vertical-dragging");this._trigger("rangeChanged",true);this.valueMin=null;this.valueMax=null},_startResizeLeft:function(a,b){a.preventDefault();if(b&&a.originalEvent.touches)a=a.originalEvent.touches[0];this.resize=true;this.pos=a.pageX;this._startChange()},_resizeLeft:function(c,e){if(!this.resize)return;c.preventDefault();if(e&&c.originalEvent.touches)c=c.originalEvent.touches[0];var g=c.pageX-this.pos,b=this.options,f=b.maximum-b.minimum,a=f*g/this.innerW,d=this.options.minRange;if(!b.reversed){a=Math.max(a,b.minimum-this.valueMin);a=Math.min(a,b.range.maximum-this.valueMin-d);b.range.minimum=this.valueMin+a}else{a=-a;a=Math.min(a,b.maximum-this.valueMax);a=Math.max(a,b.range.minimum-this.valueMax+d);b.range.maximum=this.valueMax+a}this._arrange();this._trigger("rangeChanging")},_stopResizeLeft:function(a){a.preventDefault();this.resize=false;this._trigger("rangeChanged",true);this.valueMin=null;this.valueMax=null},_startResizeBottom:function(a,b){a.preventDefault();if(b&&a.originalEvent.touches)a=a.originalEvent.touches[0];this.resize=true;this.pos=a.pageY;this._startChange()},_resizeBottom:function(c,e){if(!this.resize)return;c.preventDefault();if(e&&c.originalEvent.touches)c=c.originalEvent.touches[0];var g=this.pos-c.pageY,b=this.options,d=this.options.minRange,f=b.maximum-b.minimum,a=f*g/this.innerH;if(!b.reversed){a=Math.max(a,b.minimum-this.valueMin);a=Math.min(a,b.range.maximum-this.valueMin-d);b.range.minimum=this.valueMin+a}else{a=-a;a=Math.min(a,b.maximum-this.valueMax);a=Math.max(a,b.range.minimum-this.valueMax+d);b.range.maximum=this.valueMax+a}this._arrange();this._trigger("rangeChanging")},_stopResizeBottom:function(a){a.preventDefault();this.resize=false;this._trigger("rangeChanged",true);this.valueMin=null;this.valueMax=null},_startResizeRight:function(a,b){a.preventDefault();if(b&&a.originalEvent.touches)a=a.originalEvent.touches[0];this.resize=true;this.pos=a.pageX;this._startChange()},_resizeRight:function(c,e){if(!this.resize)return;c.preventDefault();if(e&&c.originalEvent.touches)c=c.originalEvent.touches[0];var g=c.pageX-this.pos,b=this.options,d=this.options.minRange,f=b.maximum-b.minimum,a=f*g/this.innerW;if(!b.reversed){a=Math.min(a,b.maximum-this.valueMax);a=Math.max(a,b.range.minimum-this.valueMax+d);b.range.maximum=this.valueMax+a}else{a=-a;a=Math.max(a,b.minimum-this.valueMin);a=Math.min(a,b.range.maximum-this.valueMin-d);b.range.minimum=this.valueMin+a}this._arrange();this._trigger("rangeChanging")},_stopResizeRight:function(a){a.preventDefault();this.resize=false;this._trigger("rangeChanged",true);this.valueMin=null;this.valueMax=null},_startResizeTop:function(a,b){a.preventDefault();if(b&&a.originalEvent.touches)a=a.originalEvent.touches[0];this.resize=true;this.pos=a.pageY;this._startChange()},_resizeTop:function(c,e){if(!this.resize)return;c.preventDefault();if(e&&c.originalEvent.touches)c=c.originalEvent.touches[0];var g=this.pos-c.pageY,b=this.options,d=this.options.minRange,f=b.maximum-b.minimum,a=f*g/this.innerH;if(!b.reversed){a=Math.min(a,b.maximum-this.valueMax);a=Math.max(a,b.range.minimum-this.valueMax+d);b.range.maximum=this.valueMax+a}else{a=-a;a=Math.max(a,b.minimum-this.valueMin);a=Math.min(a,b.range.maximum-this.valueMin-d);b.range.minimum=this.valueMin+a}this._arrange();this._trigger("rangeChanging")},_stopResizeTop:function(a){a.preventDefault();this.resize=false;this._trigger("rangeChanged",true);this.valueMin=null;this.valueMax=null},_outerH:function(c,b){var d=["Top","Bottom"];a.each(d,function(){b-=parseFloat(c.css("border"+this+"Width"))||0});b=Math.max(0,b);c.height(b);return c},_outerW:function(c,b){var d=["Left","Right"];a.each(d,function(){b-=parseFloat(c.css("border"+this+"Width"))||0});b=Math.max(0,b);c.width(b);return c},_addHover:function(b){b.hover(function(){a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")})},destroy:function(){var a=this.elem;a.children().remove();a.removeClass("ui-jqrangeslider ui-widget")}}})(jQuery) -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "background": { 4 | "scripts": ["sha512.js", "api/mtgox1.js", "background.js"] 5 | }, 6 | "browser_action": { 7 | "default_icon": "icon.gif", 8 | "default_popup": "popup.html" 9 | }, 10 | "description": "MtGox EMA trading bot", 11 | "icons": { 12 | "128": "icon_128.gif" 13 | }, 14 | "name": "Gox Trading Bot", 15 | "options_page": "options.html", 16 | "permissions": [ "https://mtgox.com/", "https://data.mtgox.com/", "https://vircurex.com/" ], 17 | "version": "0.2.0.5" 18 | } 19 | -------------------------------------------------------------------------------- /options.html: -------------------------------------------------------------------------------- 1 | 30 |
31 | See chart. 32 | 33 | Read Goomboo's Journal 34 | to learn about the strategy used by this trading bot.
35 | The bot uses the first traded price of each hour for the EMA input. 36 |
37 |

38 | 39 | 40 | 41 | 42 | 43 | 46 | 47 | 48 | 49 | 50 | 53 | 54 | 55 | 56 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 94 | 101 | 102 | 103 | 107 | 108 | 109 | 118 | 119 | 120 |
MtGox API Key 1 44 | 45 |
MtGox API Secret 1 51 | 52 |
57 | 58 | 59 | 60 | 61 | 62 | 72 |
EMAShort:EMALong:sellTreshold:% 2buyTreshold:% 2Show last: 63 |
73 |
Enable Trading: (Trade is off when unchecked)
82 | EMA Timeframe : 83 | 92 |
93 |
95 | Last Buy to Sell trigger: 96 | % 3
97 | Last Sell to Buy trigger: 98 | % 3
99 |
100 |
104 | 105 | 106 |
110 | background.js constants:
111 |
112 | btcAmountPreserved:  BTC
113 | MaxHoursToKeep: 
114 | btcFiat: 
115 |
116 | 117 |
121 |
122 |
123 | 1 124 | Take API Key and Secret from your MtGox account. 125 | Use Advanced API Key Creation at 126 | Security Center page 127 | to create these values. 128 | Make sure to grant only get_info and trade access rights for this API key. 129 | The bot does not need you to be logged at the MtGox account 130 | - just setup the Key&Secret, leave the browser running and it will trade... 131 |

132 | 2 133 | The bot will buy or sell all BTC above amount (preconfigured in file background.js) at the given MtGox account when the absolute difference between two EMA values (expressed in %) 134 | holds above the Threshold for the last one tick (hours). 135 |

136 | 3 137 | The bot will preserve loses by keeping last wallet state (not trading) in case buy/sell difference from last trade is less than given %. 138 | 0% means preserving loses is not active. 139 |
140 | 141 |
142 | original bot 143 |
144 |
145 | If You like modifications made from original bot 146 | send 0.01 BTC to 147 | 13eJdr8ndc3MJAeHGpVTNMPUtTGE8ANHpL 148 |
149 |
150 | If you like this extension send 0.01 BTC to 151 | 13g6zY7GJJvKEiYzTnGP8H9dEDEhYW2jFq 152 |
153 | 154 |
155 | 156 | -------------------------------------------------------------------------------- /options.js: -------------------------------------------------------------------------------- 1 | 2 | var bp = chrome.extension.getBackgroundPage() 3 | var sla = document.getElementById("sla") 4 | var tf = document.getElementById("tf") 5 | 6 | function rese() { 7 | document.getElementById("emas").value=10 8 | document.getElementById("emal").value=21 9 | document.getElementById("btras").value=0.25 10 | document.getElementById("stras").value=0.25 11 | document.getElementById("bsTrigSell").value=0; 12 | document.getElementById("bsTrigBuy").value=0; 13 | //document.getElementById("bsTrig2").value=0; 14 | 15 | document.getElementById("tradingEnabled").checked = true; 16 | 17 | sla.selectedIndex=1 18 | tf.selectedIndex=0 19 | } 20 | 21 | function save() { 22 | var btr = parseFloat(document.getElementById("btras").value) 23 | if (isNaN(btr) || btr<0 || btr>10) { 24 | alert("Wrong buyTreshold parameter") 25 | return 26 | } 27 | 28 | var str = parseFloat(document.getElementById("stras").value) 29 | if (isNaN(str) || str<0 || str>10) { 30 | alert("Wrong sellTreshold parameter") 31 | return 32 | } 33 | 34 | var es = parseInt(document.getElementById("emas").value) 35 | var el = parseInt(document.getElementById("emal").value) 36 | if (isNaN(es) || isNaN(el)) { 37 | alert("Wrong EMA parameter") 38 | return 39 | } 40 | 41 | if (es==el) { 42 | alert("The EMA parameters must be different") 43 | return 44 | } 45 | 46 | if (es<1 || el<1) { 47 | alert("EMA parameter must be bigger than 1") 48 | return 49 | } 50 | 51 | if (es>bp.MaxHoursBack || el>bp.MaxHoursBack) { 52 | alert("EMA parameter too big - max is "+bp.MaxHoursBack) 53 | return 54 | } 55 | 56 | if (es > el) { 57 | var tmp = es 58 | es = el 59 | el = tmp 60 | document.getElementById("emas").value=es 61 | document.getElementById("emal").value=el 62 | } 63 | 64 | if (bp.EmaShortPar!=es || bp.EmaLongPar!=el || bp.MinThresholdBuy!=btr || bp.MinThresholdSell!=str) { 65 | if (!confirm("Applying different EMA/Treshold values may case an instant trigger to execute a trade.")) return 66 | } 67 | 68 | localStorage.ApiKey=bp.ApiKey=document.getElementById("apikey").value 69 | localStorage.ApiSec=bp.ApiSec=document.getElementById("apisec").value 70 | 71 | localStorage.tradingEnabled=bp.tradingEnabled=(document.getElementById("tradingEnabled").checked?1:0); 72 | localStorage.bsTrigSell=bp.bsTrigSell=parseInt(document.getElementById("bsTrigSell").value); 73 | localStorage.bsTrigBuy=bp.bsTrigBuy=parseInt(document.getElementById("bsTrigBuy").value); 74 | 75 | bp.schedupdate(10) 76 | 77 | localStorage.LogLines=bp.LogLines=parseInt(sla.value) 78 | localStorage.TimeFrame=bp.TimeFrame=parseInt(tf.value) 79 | 80 | localStorage.EmaShortPar=bp.EmaShortPar=es 81 | localStorage.EmaLongPar=bp.EmaLongPar=el 82 | localStorage.MinThresholdBuy=bp.MinThresholdBuy=btr 83 | localStorage.MinThresholdSell=bp.MinThresholdSell=str 84 | bp.refreshEMA(true) 85 | } 86 | 87 | function setfields() { 88 | document.getElementById("apikey").value=bp.ApiKey 89 | document.getElementById("apisec").value=bp.ApiSec 90 | document.getElementById("emas").value=bp.EmaShortPar.toString() 91 | document.getElementById("emal").value=bp.EmaLongPar.toString() 92 | document.getElementById("btras").value=bp.MinThresholdBuy.toFixed(2) 93 | document.getElementById("stras").value=bp.MinThresholdSell.toFixed(2) 94 | document.getElementById("bsTrigSell").value = bp.bsTrigSell.toString(); 95 | document.getElementById("bsTrigBuy").value = bp.bsTrigBuy.toString(); 96 | 97 | 98 | document.getElementById("tradingEnabled").checked=(bp.tradingEnabled==1); 99 | document.getElementById("btcPreserve").innerHTML = ""+bp.btcPreserve+" BTC "; 100 | document.getElementById("btcAmountPreserved").innerHTML = "" + bp.btcPreserve; 101 | document.getElementById("MaxHoursToKeep").innerHTML = "" + bp.MaxHoursToKeep; 102 | document.getElementById("btcFiat").innerHTML = "" + bp.btcFiat; 103 | 104 | 105 | for (var i=0; i 2 | 3 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 19 | 20 | 21 | 24 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | 38 | 39 | 40 | 43 | 46 | 47 | 48 | 49 | 50 |
17 | 18 |
22 | See options 23 | 25 | 26 |
32 | Problem accessing MtGox account.
33 | Some chart. 34 | Go check the Options page. 35 |
41 | See chart 42 | 44 | Balance = 0.00 BTC + 0.00 45 |
HourPriceEMA(a) / EMA(b) 51 |
52 | 53 | 54 |
55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /popup.js: -------------------------------------------------------------------------------- 1 | var bp = chrome.extension.getBackgroundPage() 2 | function padit(d) { 3 | return d<10 ? '0'+d : d.toString() 4 | } 5 | 6 | function hrRefreshOnClick(){ 7 | //bp.refreshEMA(true); 8 | //refreshtable(); 9 | } 10 | 11 | function refreshtable() { 12 | const wds = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"] 13 | const bcols = ["#f2f2ff", "#fffff0"] 14 | var tab = document.getElementById("tab") 15 | document.getElementById("emal").innerHTML=bp.EmaLongPar 16 | document.getElementById("emas").innerHTML=bp.EmaShortPar 17 | 18 | document.getElementById("tradingStatus").innerHTML=(bp.tradingEnabled==1?"Trading is enabled
":"Trading is disabled
"); 19 | 20 | while (tab.rows.length>5) tab.deleteRow(1) 21 | 22 | if (bp.updateinprogress) { // && bp.H1.length>bp.LogLines) { 23 | var r=tab.insertRow(4); 24 | var c=r.insertCell(-1); 25 | c.colSpan=5; 26 | c.innerHTML=" 
Fetching trading data - please wait...
("+bp.H1.length+" of "+bp.MaxHoursToKeep+" samples loaded)
 "; 27 | c.style.backgroundColor="#FFFFFF"; 28 | c.style.textAlign="center"; 29 | c.id="loadCell"; 30 | } 31 | 32 | if (!bp.updateinprogress && bp.H1.length>bp.LogLines) { 33 | if (bp.H1.length>bp.emaLong.length){ 34 | bp.refreshEMA(true); 35 | } 36 | for (var i=bp.H1.length-bp.LogLines; ii) && (bp.emaShort.length>i)) { 38 | var el = bp.emaLong[i]; 39 | var es = bp.emaShort[i]; 40 | 41 | var perc = 0; 42 | if ((es + el)>0) { 43 | perc = 100 * (es-el) / ((es+el)/2) 44 | } 45 | var r=tab.insertRow(5) 46 | var ti=new Date(bp.tim[i]*bp.TimeFrame*1000) 47 | // new Date(bp.tim[i]*3600*1000) 48 | r.style.backgroundColor=bcols[((bp.tim[i]+1)/24)&1] 49 | r.title=wds[ti.getDay()] 50 | 51 | var mnts = ti.getMinutes().toString(); 52 | if (mnts.length<2) mnts = '0'+mnts; 53 | var hrss = ti.getHours().toString(); 54 | if (hrss.length<2) hrss = '0'+hrss; 55 | 56 | r.insertCell(-1).innerHTML= hrss + ":"+ mnts; 57 | r.insertCell(-1).innerHTML=bp.H1[i].toFixed(4) 58 | r.insertCell(-1).innerHTML=es.toFixed(4) 59 | r.insertCell(-1).innerHTML=el.toFixed(4) 60 | var c=r.insertCell(-1) 61 | c.innerHTML=perc.toFixed(4)+'%' 62 | if (perc>bp.MinThresholdBuy || perc<-bp.MinThresholdSell) { 63 | c.style.backgroundColor = perc<0 ? "#ffd0d0" : "#d0ffd0" 64 | } else { 65 | c.style.backgroundColor = perc<0 ? "#fff0f0" : "#f0fff0" 66 | } 67 | } 68 | 69 | } 70 | } 71 | if (isNaN(bp.USD) || isNaN(bp.BTC)) { 72 | document.getElementById("nobalan").style.display="table-row" 73 | document.getElementById("balance").style.display="none" 74 | } else { 75 | document.getElementById("nobalan").style.display="none" 76 | document.getElementById("balance").style.display="table-row" 77 | document.getElementById("usd").innerHTML=bp.USD.toFixed(2)+" "+ bp.btcFiat; 78 | document.getElementById("btc").innerHTML=bp.BTC.toFixed(2) 79 | } 80 | } 81 | 82 | 83 | function popupUpdateCounter() { 84 | var o=document.getElementById("loadCell"); 85 | if (o) { 86 | o.innerHTML=" 
Fetching trading data - please wait...
("+bp.H1.length+" of "+bp.MaxHoursToKeep+" samples loaded)
 "; 87 | } 88 | //redrawChart(); 89 | } 90 | 91 | document.getElementById("hrRefresh").onclick=hrRefreshOnClick; 92 | refreshtable(); 93 | bp.popupRefresh=refreshtable; 94 | bp.popupUpdateCounter=popupUpdateCounter; 95 | -------------------------------------------------------------------------------- /sha512.js: -------------------------------------------------------------------------------- 1 | /* A JavaScript implementation of the SHA family of hashes, as defined in FIPS 2 | * PUB 180-2 as well as the corresponding HMAC implementation as defined in 3 | * FIPS PUB 198a 4 | * 5 | * Version 1.3 Copyright Brian Turek 2008-2010 6 | * Distributed under the BSD License 7 | * See http://jssha.sourceforge.net/ for more information 8 | * 9 | * Several functions taken from Paul Johnson 10 | */ 11 | (function(){var charSize=8,b64pad="",hexCase=0,Int_64=function(a,b){this.highOrder=a;this.lowOrder=b},str2binb=function(a){var b=[],mask=(1<>5]|=(a.charCodeAt(i/charSize)&mask)<<(32-charSize-(i%32))}return b},hex2binb=function(a){var b=[],length=a.length,i,num;for(i=0;i>3]|=num<<(24-(4*(i%8)))}else{return"INVALID HEX STRING"}}return b},binb2hex=function(a){var b=(hexCase)?"0123456789ABCDEF":"0123456789abcdef",str="",length=a.length*4,i,srcByte;for(i=0;i>2]>>((3-(i%4))*8);str+=b.charAt((srcByte>>4)&0xF)+b.charAt(srcByte&0xF)}return str},binb2b64=function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"+"0123456789+/",str="",length=a.length*4,i,j,triplet;for(i=0;i>2]>>8*(3-i%4))&0xFF)<<16)|(((a[i+1>>2]>>8*(3-(i+1)%4))&0xFF)<<8)|((a[i+2>>2]>>8*(3-(i+2)%4))&0xFF);for(j=0;j<4;j+=1){if(i*8+j*6<=a.length*32){str+=b.charAt((triplet>>6*(3-j))&0x3F)}else{str+=b64pad}}}return str},rotr=function(x,n){if(n<=32){return new Int_64((x.highOrder>>>n)|(x.lowOrder<<(32-n)),(x.lowOrder>>>n)|(x.highOrder<<(32-n)))}else{return new Int_64((x.lowOrder>>>n)|(x.highOrder<<(32-n)),(x.highOrder>>>n)|(x.lowOrder<<(32-n)))}},shr=function(x,n){if(n<=32){return new Int_64(x.highOrder>>>n,x.lowOrder>>>n|(x.highOrder<<(32-n)))}else{return new Int_64(0,x.highOrder<<(32-n))}},ch=function(x,y,z){return new Int_64((x.highOrder&y.highOrder)^(~x.highOrder&z.highOrder),(x.lowOrder&y.lowOrder)^(~x.lowOrder&z.lowOrder))},maj=function(x,y,z){return new Int_64((x.highOrder&y.highOrder)^(x.highOrder&z.highOrder)^(y.highOrder&z.highOrder),(x.lowOrder&y.lowOrder)^(x.lowOrder&z.lowOrder)^(y.lowOrder&z.lowOrder))},sigma0=function(x){var a=rotr(x,28),rotr34=rotr(x,34),rotr39=rotr(x,39);return new Int_64(a.highOrder^rotr34.highOrder^rotr39.highOrder,a.lowOrder^rotr34.lowOrder^rotr39.lowOrder)},sigma1=function(x){var a=rotr(x,14),rotr18=rotr(x,18),rotr41=rotr(x,41);return new Int_64(a.highOrder^rotr18.highOrder^rotr41.highOrder,a.lowOrder^rotr18.lowOrder^rotr41.lowOrder)},gamma0=function(x){var a=rotr(x,1),rotr8=rotr(x,8),shr7=shr(x,7);return new Int_64(a.highOrder^rotr8.highOrder^shr7.highOrder,a.lowOrder^rotr8.lowOrder^shr7.lowOrder)},gamma1=function(x){var a=rotr(x,19),rotr61=rotr(x,61),shr6=shr(x,6);return new Int_64(a.highOrder^rotr61.highOrder^shr6.highOrder,a.lowOrder^rotr61.lowOrder^shr6.lowOrder)},safeAdd_2=function(x,y){var a,msw,lowOrder,highOrder;a=(x.lowOrder&0xFFFF)+(y.lowOrder&0xFFFF);msw=(x.lowOrder>>>16)+(y.lowOrder>>>16)+(a>>>16);lowOrder=((msw&0xFFFF)<<16)|(a&0xFFFF);a=(x.highOrder&0xFFFF)+(y.highOrder&0xFFFF)+(msw>>>16);msw=(x.highOrder>>>16)+(y.highOrder>>>16)+(a>>>16);highOrder=((msw&0xFFFF)<<16)|(a&0xFFFF);return new Int_64(highOrder,lowOrder)},safeAdd_4=function(a,b,c,d){var e,msw,lowOrder,highOrder;e=(a.lowOrder&0xFFFF)+(b.lowOrder&0xFFFF)+(c.lowOrder&0xFFFF)+(d.lowOrder&0xFFFF);msw=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c.lowOrder>>>16)+(d.lowOrder>>>16)+(e>>>16);lowOrder=((msw&0xFFFF)<<16)|(e&0xFFFF);e=(a.highOrder&0xFFFF)+(b.highOrder&0xFFFF)+(c.highOrder&0xFFFF)+(d.highOrder&0xFFFF)+(msw>>>16);msw=(a.highOrder>>>16)+(b.highOrder>>>16)+(c.highOrder>>>16)+(d.highOrder>>>16)+(e>>>16);highOrder=((msw&0xFFFF)<<16)|(e&0xFFFF);return new Int_64(highOrder,lowOrder)},safeAdd_5=function(a,b,c,d,e){var f,msw,lowOrder,highOrder;f=(a.lowOrder&0xFFFF)+(b.lowOrder&0xFFFF)+(c.lowOrder&0xFFFF)+(d.lowOrder&0xFFFF)+(e.lowOrder&0xFFFF);msw=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c.lowOrder>>>16)+(d.lowOrder>>>16)+(e.lowOrder>>>16)+(f>>>16);lowOrder=((msw&0xFFFF)<<16)|(f&0xFFFF);f=(a.highOrder&0xFFFF)+(b.highOrder&0xFFFF)+(c.highOrder&0xFFFF)+(d.highOrder&0xFFFF)+(e.highOrder&0xFFFF)+(msw>>>16);msw=(a.highOrder>>>16)+(b.highOrder>>>16)+(c.highOrder>>>16)+(d.highOrder>>>16)+(e.highOrder>>>16)+(f>>>16);highOrder=((msw&0xFFFF)<<16)|(f&0xFFFF);return new Int_64(highOrder,lowOrder)},coreSHA2=function(j,k,l){var a,b,c,d,e,f,g,h,T1,T2,H,lengthPosition,i,t,K,W=[],appendedMessageLength;if(l==="SHA-384"||l==="SHA-512"){lengthPosition=(((k+128)>>10)<<5)+31;K=[new Int_64(0x428a2f98,0xd728ae22),new Int_64(0x71374491,0x23ef65cd),new Int_64(0xb5c0fbcf,0xec4d3b2f),new Int_64(0xe9b5dba5,0x8189dbbc),new Int_64(0x3956c25b,0xf348b538),new Int_64(0x59f111f1,0xb605d019),new Int_64(0x923f82a4,0xaf194f9b),new Int_64(0xab1c5ed5,0xda6d8118),new Int_64(0xd807aa98,0xa3030242),new Int_64(0x12835b01,0x45706fbe),new Int_64(0x243185be,0x4ee4b28c),new Int_64(0x550c7dc3,0xd5ffb4e2),new Int_64(0x72be5d74,0xf27b896f),new Int_64(0x80deb1fe,0x3b1696b1),new Int_64(0x9bdc06a7,0x25c71235),new Int_64(0xc19bf174,0xcf692694),new Int_64(0xe49b69c1,0x9ef14ad2),new Int_64(0xefbe4786,0x384f25e3),new Int_64(0x0fc19dc6,0x8b8cd5b5),new Int_64(0x240ca1cc,0x77ac9c65),new Int_64(0x2de92c6f,0x592b0275),new Int_64(0x4a7484aa,0x6ea6e483),new Int_64(0x5cb0a9dc,0xbd41fbd4),new Int_64(0x76f988da,0x831153b5),new Int_64(0x983e5152,0xee66dfab),new Int_64(0xa831c66d,0x2db43210),new Int_64(0xb00327c8,0x98fb213f),new Int_64(0xbf597fc7,0xbeef0ee4),new Int_64(0xc6e00bf3,0x3da88fc2),new Int_64(0xd5a79147,0x930aa725),new Int_64(0x06ca6351,0xe003826f),new Int_64(0x14292967,0x0a0e6e70),new Int_64(0x27b70a85,0x46d22ffc),new Int_64(0x2e1b2138,0x5c26c926),new Int_64(0x4d2c6dfc,0x5ac42aed),new Int_64(0x53380d13,0x9d95b3df),new Int_64(0x650a7354,0x8baf63de),new Int_64(0x766a0abb,0x3c77b2a8),new Int_64(0x81c2c92e,0x47edaee6),new Int_64(0x92722c85,0x1482353b),new Int_64(0xa2bfe8a1,0x4cf10364),new Int_64(0xa81a664b,0xbc423001),new Int_64(0xc24b8b70,0xd0f89791),new Int_64(0xc76c51a3,0x0654be30),new Int_64(0xd192e819,0xd6ef5218),new Int_64(0xd6990624,0x5565a910),new Int_64(0xf40e3585,0x5771202a),new Int_64(0x106aa070,0x32bbd1b8),new Int_64(0x19a4c116,0xb8d2d0c8),new Int_64(0x1e376c08,0x5141ab53),new Int_64(0x2748774c,0xdf8eeb99),new Int_64(0x34b0bcb5,0xe19b48a8),new Int_64(0x391c0cb3,0xc5c95a63),new Int_64(0x4ed8aa4a,0xe3418acb),new Int_64(0x5b9cca4f,0x7763e373),new Int_64(0x682e6ff3,0xd6b2b8a3),new Int_64(0x748f82ee,0x5defb2fc),new Int_64(0x78a5636f,0x43172f60),new Int_64(0x84c87814,0xa1f0ab72),new Int_64(0x8cc70208,0x1a6439ec),new Int_64(0x90befffa,0x23631e28),new Int_64(0xa4506ceb,0xde82bde9),new Int_64(0xbef9a3f7,0xb2c67915),new Int_64(0xc67178f2,0xe372532b),new Int_64(0xca273ece,0xea26619c),new Int_64(0xd186b8c7,0x21c0c207),new Int_64(0xeada7dd6,0xcde0eb1e),new Int_64(0xf57d4f7f,0xee6ed178),new Int_64(0x06f067aa,0x72176fba),new Int_64(0x0a637dc5,0xa2c898a6),new Int_64(0x113f9804,0xbef90dae),new Int_64(0x1b710b35,0x131c471b),new Int_64(0x28db77f5,0x23047d84),new Int_64(0x32caab7b,0x40c72493),new Int_64(0x3c9ebe0a,0x15c9bebc),new Int_64(0x431d67c4,0x9c100d4c),new Int_64(0x4cc5d4be,0xcb3e42b6),new Int_64(0x597f299c,0xfc657e2a),new Int_64(0x5fcb6fab,0x3ad6faec),new Int_64(0x6c44198c,0x4a475817)];if(l==="SHA-384"){H=[new Int_64(0xcbbb9d5d,0xc1059ed8),new Int_64(0x0629a292a,0x367cd507),new Int_64(0x9159015a,0x3070dd17),new Int_64(0x0152fecd8,0xf70e5939),new Int_64(0x67332667,0xffc00b31),new Int_64(0x98eb44a87,0x68581511),new Int_64(0xdb0c2e0d,0x64f98fa7),new Int_64(0x047b5481d,0xbefa4fa4)]}else{H=[new Int_64(0x6a09e667,0xf3bcc908),new Int_64(0xbb67ae85,0x84caa73b),new Int_64(0x3c6ef372,0xfe94f82b),new Int_64(0xa54ff53a,0x5f1d36f1),new Int_64(0x510e527f,0xade682d1),new Int_64(0x9b05688c,0x2b3e6c1f),new Int_64(0x1f83d9ab,0xfb41bd6b),new Int_64(0x5be0cd19,0x137e2179)]}}j[k>>5]|=0x80<<(24-k%32);j[lengthPosition]=k;appendedMessageLength=j.length;for(i=0;i(keyBinLen/8)){keyToUse[31]&=0xFFFFFF00}for(i=0;i<=31;i+=1){keyWithIPad[i]=keyToUse[i]^0x36363636;keyWithOPad[i]=keyToUse[i]^0x5C5C5C5C}retVal=coreSHA2(keyWithIPad.concat(this.strToHash),1024+this.strBinLen,c);retVal=coreSHA2(keyWithOPad.concat(retVal),1024+hashBitSize,c);return(e(retVal))}};window.jsSHA=jsSHA}()); 12 | 13 | --------------------------------------------------------------------------------