├── .gitignore ├── LICENSE ├── PSD ├── main-bg.psd └── tout-slides.psd ├── README.md ├── app.html ├── app.xml ├── colors.herro ├── compress.cmd ├── default.css ├── default.min.css ├── detect.cmd ├── font ├── OpenSans-Bold-webfont.ttf ├── OpenSans-Bold-webfont.woff ├── OpenSans-Light-webfont.ttf ├── OpenSans-Light-webfont.woff ├── OpenSans-Regular-webfont.ttf ├── OpenSans-Regular-webfont.woff ├── OpenSans-Semibold-webfont.ttf └── OpenSans-Semibold-webfont.woff ├── img ├── 128x128.png ├── 16x16.png ├── 32x32.png ├── 4.gif ├── 48x48.png ├── activity │ ├── connect.png │ ├── detected.png │ ├── line.png │ └── scrobbled.png ├── app-shadow-darker.png ├── app-shadow.png ├── bgs │ ├── kuma.jpg │ ├── login-bg.png │ ├── main-bg-w.png │ ├── main-bg.png │ ├── sombrero.png │ └── tama.jpg ├── chev-left.png ├── chev-right.png ├── guide-bg.png ├── hb-mini.png ├── herro-mini.png ├── icon-popout.png ├── loading.png ├── login-logo-h.png ├── login-logo-text.png ├── login-logo.png ├── middle-open.png ├── nicons │ ├── check.jpg │ ├── scrobble.jpg │ └── update.jpg ├── note-gloss.png ├── note.png ├── note_2.png ├── para-1.png ├── para-2.png ├── settings.png ├── top-bg.png ├── top-close.png ├── top-minimize.png ├── tour-1.png ├── tour-2-old.png ├── tour-2.png ├── tour-3-old.png ├── tour-3.png ├── tour-4.png ├── tour-bg.png └── tour.png ├── js ├── AIRAliases.js ├── AIRAliases.min.js ├── app.js ├── app.min.js ├── lib.js ├── lib.min.js └── parallax_mod.js ├── note.html ├── sc.cmd └── version /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | build.cmd 3 | generateCert.cmd 4 | certificate.p12 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Dennis Jin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /PSD/main-bg.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/PSD/main-bg.psd -------------------------------------------------------------------------------- /PSD/tout-slides.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/PSD/tout-slides.psd -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ####Setup Instructions Windows/Whatever 2 | 3 | 1. Download the latest Adobe Air SDK from http://www.adobe.com/devnet/air/air-sdk-download.html 4 | 2. Install it and add the bin directory to your `$PATH`. 5 | 3. Clone this repository add run `adl app.xml` to start the application. 6 | 4. There is no `console.log()` which sucks. Use `air.trace()` instead for logging. 7 | 8 | ####About contributing 9 | 10 | Code is super ugly. If you want to contribute, be sure to look through the code before trying anything. 11 | 12 | ####Screenshots + video 13 | 14 | #####[Video of application in use](https://2.sendvid.com/vik5aftu.mp4) 15 | ![](http://u.cubeupload.com/Horo/NDzir0.png) 16 | ![](http://u.cubeupload.com/Horo/76RNp4.png) 17 | -------------------------------------------------------------------------------- /app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | 24 |
25 |
26 |
27 |
28 |
29 | 33 |
34 | 35 | View List 36 | 37 |
38 | Settings 39 |
40 | 44 |
45 | 49 |
50 |
51 |
52 |
53 |
54 | Take a tour 55 |
56 |
57 | or simply skip it 58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | Settings 75 |
76 |
77 |
78 |
79 |
Take the Tour
80 |
Short introduction about the features
81 |
82 |
83 |
84 | View 85 |
86 |
87 |
88 |
89 |
90 |
Clear Recent Activity
91 |
(You will still be logged in)
92 |
93 |
94 |
95 | Clear 96 |
97 |
98 |
99 |
100 |
101 |
Clear Everything
102 |
Removes ALL user information and logs you out.
103 |
104 |
105 |
106 | Clear 107 |
108 |
109 |
110 |
111 |
112 | Close Settings 113 |
114 |
115 |
116 | 117 |
118 |
119 |
120 | 123 |
124 |
125 | 128 | 131 | 134 |
135 | Connect 136 |
137 | 141 |
142 |
143 |
144 |
145 | 146 | -------------------------------------------------------------------------------- /app.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hummingbird 4 | 0.0.7 5 | Hummingbird Updater 6 | Hummingbird Updater 7 | Light-weight scrobbler for Hummingbird 8 | © Dennis Jin 9 | extendedDesktop 10 | 11 | app.html 12 | none 13 | true 14 | true 15 | false 16 | 388 17 | 628 18 | 19 | 20 | 21 | img/128x128.png 22 | 23 | 24 | img/48x48.png 25 | 26 | 27 | img/32x32.png 28 | 29 | 30 | img/16x16.png 31 | 32 | 33 | -------------------------------------------------------------------------------- /colors.herro: -------------------------------------------------------------------------------- 1 | GREEN 2 | MEDIUM 4ec22e 3 | DARK 3d9924 4 | DARKEST 2d701a 5 | TAG GREEN 6 | MEDIUM 92c836 7 | FEED GREEN 8 | MEDIUM 52b766 9 | ORANGE 10 | MEDIUM ff9032 11 | BRIGHT ffab63 12 | DARK f77d15 13 | SUPER BRIGHT ffc695 14 | BLACK 15 | BRIGHT eee 16 | A BIT DARKER d5d5d5 17 | GRAY bbb 18 | DARK 515151 19 | SUPER DARK 333333 20 | BLUE 21 | MEDIUM 4b99f0 22 | BRIGHT 7ab4f4 23 | DARK 1c7eec 24 | SUPER BRIGHT a9cef8 25 | WHITE f8fbfe 26 | APP BG eef5fc 27 | SEA BLUE 28 | WHITE (ALMOST) f9f9fa 29 | BRIGHT 89909e 30 | MEDIUM 575d6a 31 | DARK 292c32 32 | YELLOWISH 33 | MEDIUM edebde 34 | BLUE GRAY 35 | LIGHT LIGHT f2f4f8 36 | GRAYSCALE 37 | LIGHTER f8f8f8 38 | LIGHT eee 39 | MEDIUM-LIGHT (+4) ddd 40 | MEDIUM bbb 41 | MEDIUM-DARK (-6) 888 42 | DARK 515151 43 | DARKEST 333 44 | ALMOST BLACK 111 45 | RED 46 | MEDIUM ec464e 47 | DARK b9131b 48 | DAKEST 5d0a0e -------------------------------------------------------------------------------- /compress.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | uglifyjs js\AIRAliases.js -o js\AIRAliases.min.js -c -m && uglifyjs js\lib.js -o js\lib.min.js -c -m && uglifyjs js\app.js -o js\app.min.js -c -m && uglifycss default.css > default.min.css -------------------------------------------------------------------------------- /default.css: -------------------------------------------------------------------------------- 1 | /* 2 | YUI 3.12.0 (build 8655935) 3 | Copyright 2013 Yahoo! Inc. All rights reserved. 4 | Licensed under the BSD License. 5 | http://yuilibrary.com/license/ 6 | */ 7 | 8 | html{color:#000;background:#FFF}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}input,textarea,select{*font-size:100%}legend{color:#000}#yui3-css-stamp.cssreset{display:none} 9 | 10 | /* Seeting up @font-face */ 11 | 12 | @font-face { 13 | font-family: 'open_sansbold'; 14 | src: url('font/OpenSans-Bold-webfont.woff') format('woff'), 15 | url('font/OpenSans-Bold-webfont.ttf') format('truetype'); 16 | font-weight: normal; 17 | font-style: normal; 18 | } 19 | @font-face { 20 | font-family: 'open_sanslight'; 21 | src: url('font/OpenSans-Light-webfont.woff') format('woff'), 22 | url('font/OpenSans-Light-webfont.ttf') format('truetype'); 23 | font-weight: normal; 24 | font-style: normal; 25 | } 26 | @font-face { 27 | font-family: 'open_sansregular'; 28 | src: url('font/OpenSans-Regular-webfont.woff') format('woff'), 29 | url('font/OpenSans-Regular-webfont.ttf') format('truetype'); 30 | font-weight: normal; 31 | font-style: normal; 32 | } 33 | @font-face { 34 | font-family: 'open_sanssemibold'; 35 | src: url('font/OpenSans-Semibold-webfont.woff') format('woff'), 36 | url('font/OpenSans-Semibold-webfont.ttf') format('truetype'); 37 | font-weight: normal; 38 | font-style: normal; 39 | } 40 | .openbold { 41 | font-family: 'open_sansbold', sans-serif; 42 | } 43 | .openlight { 44 | font-family: 'open_sanslight', sans-serif; 45 | } 46 | .openregular { 47 | font-family: 'open_sansregular', sans-serif; 48 | } 49 | .opensemi { 50 | font-family: 'open_sanssemibold', sans-serif; 51 | } 52 | 53 | /* Helpers */ 54 | 55 | .cf:before, .cf:after { 56 | content: " "; 57 | display: table; 58 | } 59 | .cf:after { 60 | clear: both; 61 | } 62 | .ts { 63 | -webkit-transition: 0.1s ease all; 64 | } 65 | .ts2 { 66 | -webkit-transition: 0.5s ease all; 67 | } 68 | .ns { 69 | -webkit-user-select:none; 70 | } 71 | #loading { 72 | opacity: 0; 73 | position: absolute; 74 | bottom: -50px; 75 | left: 69px; 76 | margin-top: 1px; 77 | padding-left: 31px; 78 | height: 49px; 79 | line-height: 49px; 80 | color: #89909e; 81 | background: #292c32 url(img/4.gif) center left no-repeat; 82 | } 83 | #loading.visible { 84 | opacity: 1; 85 | bottom: 0; 86 | } 87 | /* App */ 88 | 89 | html { 90 | -webkit-transform: translateZ(0); 91 | padding-top: 14px; 92 | width: 388px; 93 | height: 614px; 94 | background: url(img/app-shadow-darker.png) center center no-repeat; 95 | } 96 | body { 97 | overflow: hidden; 98 | margin: 0 auto; 99 | width: 360px; 100 | height: 600px; 101 | font-size: 13px; 102 | font-family: 'Helvetica Neue', 'Helvetica', arial, sans-serif; 103 | background: #fff; 104 | border-radius: 4px; 105 | border-top-left-radius: 8px; 106 | border-top-right-radius: 8px; 107 | } 108 | 109 | a, a:visited { 110 | color: #4b99f0; 111 | text-decoration: none; 112 | } 113 | a:hover { 114 | text-decoration: underline; 115 | } 116 | 117 | #app-wrap { 118 | overflow: hidden; 119 | position: relative; 120 | } 121 | #top { 122 | cursor: default; 123 | overflow: hidden; 124 | position: relative; 125 | height: 50px; 126 | background: #292c32; 127 | border-top-left-radius: 4px; 128 | border-top-right-radius: 4px; 129 | -webkit-box-shadow: inset 0 1px 0 #34373c; 130 | } 131 | 132 | #top-user { 133 | float: left; 134 | padding-left: 15px; 135 | height: 50px; 136 | color: #fff; 137 | line-height: 50px; 138 | border-left: 1px solid #34373c; 139 | } 140 | #top-logo { 141 | float: left; 142 | padding: 0 15px; 143 | width: 23px; 144 | height: 50px; 145 | border-right: 1px solid rgba(0,0,0,0.2); 146 | background: url(img/hb-mini.png) center center no-repeat; 147 | } 148 | #top-controls { 149 | float: right; 150 | } 151 | #top-minimize { 152 | float: left; 153 | margin: 17px 17px 0 0; 154 | width: 16px; 155 | height: 16px; 156 | background: url(img/top-minimize.png) center center no-repeat; 157 | } 158 | #top-close { 159 | float: left; 160 | margin: 17px 17px 0 0; 161 | width: 16px; 162 | height: 16px; 163 | background: url(img/top-close.png) center center no-repeat; 164 | } 165 | #top-close:hover, #top-minimize:hover { 166 | cursor: pointer; 167 | opacity: 0.7; 168 | } 169 | 170 | /* Middle */ 171 | 172 | #middle { 173 | overflow-x: hidden; 174 | overflow-y: scroll; 175 | height: 500px; 176 | background-color: #eef5fc; 177 | background-repeat: no-repeat; 178 | background-position: center center; 179 | background-image: url(img/bgs/main-bg-w.png); 180 | /* border-right: 5px solid #eef5fc; */ 181 | } 182 | #middle.new { 183 | background-image: url(img/tour-4.png); 184 | } 185 | #middle::-webkit-scrollbar { 186 | width: 5px; 187 | height: 5px; 188 | } 189 | #middle::-webkit-scrollbar-button { 190 | display: none; 191 | } 192 | #middle::-webkit-scrollbar-track-piece { 193 | background: transparent; 194 | } 195 | #middle::-webkit-scrollbar-thumb { 196 | background: rgba(0,0,0,0.3); 197 | border-radius: 0px; 198 | } 199 | #middle::-webkit-scrollbar-track { 200 | padding: 2px; 201 | background: rgba(0,0,0,0.2); 202 | border-radius: 0px; 203 | } 204 | #middle::-webkit-scrollbar-button:start:decrement{ 205 | display: block; 206 | height: 0px; 207 | } 208 | #middle::-webkit-scrollbar-button:end:increment{ 209 | display: block; 210 | height: 0px; 211 | } 212 | 213 | 214 | /* Bottom */ 215 | 216 | #bottom { 217 | border-top: 2px solid transparent; 218 | height: 50px; 219 | background: #fff; 220 | border-bottom-right-radius: 4px; 221 | border-bottom-left-radius: 4px; 222 | } 223 | #bottom.toured { 224 | border-top: 2px solid #4b99f0; 225 | } 226 | 227 | .bottom-menu-item { 228 | cursor: pointer; 229 | float: left; 230 | padding: 0 15px 0 43px; 231 | width: 121px; 232 | color: #515151; 233 | font-size: 14px; 234 | font-weight: bold; 235 | line-height: 50px; 236 | border-right: 1px solid #e0e0e0; 237 | text-decoration: none; 238 | text-align: left; 239 | background-position: 15px center; 240 | background-repeat: no-repeat; 241 | } 242 | .bottom-menu-item:hover { 243 | opacity: 0.7; 244 | text-decoration: none; 245 | } 246 | .bottom-menu-item:last-child { 247 | margin: 0; 248 | border-right: 0; 249 | } 250 | #open-herro { 251 | background-image: url(img/middle-open.png); 252 | } 253 | #open-tour { 254 | background-image: url(img/tour.png); 255 | } 256 | #open-settings { 257 | background-image: url(img/settings.png); 258 | } 259 | 260 | 261 | /* Login */ 262 | 263 | #login-form-wrap { 264 | display: none; 265 | overflow: hidden; 266 | position: absolute; 267 | top: 50px; 268 | left: 0; 269 | right: 0; 270 | bottom: 0; 271 | border-bottom-right-radius: 4px; 272 | border-bottom-left-radius: 4px; 273 | } 274 | #login-form-ovl { 275 | position: relative; 276 | z-index: 100; 277 | height: 100%; 278 | background: rgba(0,0,0,0.3); 279 | border-bottom-right-radius: 4px; 280 | border-bottom-left-radius: 4px; 281 | } 282 | #login-form-logo { 283 | width: 360px; 284 | height: 250px; 285 | background: url(img/login-logo-text.png) center center no-repeat; 286 | } 287 | .login-form-section { 288 | padding-bottom: 15px; 289 | text-align: center; 290 | } 291 | .login-form-input { 292 | outline: none; 293 | padding: 11px; 294 | width: 270px; 295 | font-size: 14px; 296 | border-radius: 2px; 297 | background: #e0e0e0; 298 | border: none; 299 | -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.3); 300 | } 301 | .login-form-input:focus { 302 | background: #fff; 303 | -webkit-box-shadow: none; 304 | } 305 | .login-form-about { 306 | padding-top: 72px; 307 | color: #cfcfcf; 308 | font-size: 11px; 309 | text-align: center; 310 | line-height: 2em; 311 | text-shadow: 0 1px 0 rgba(0,0,0,0.3); 312 | } 313 | #login-form-submit { 314 | cursor: pointer; 315 | margin: 0 0 15px 35px; 316 | padding: 10px 0; 317 | width: 290px; 318 | color: #fff; 319 | text-align: center; 320 | text-transform: uppercase; 321 | background: #4b99f0; 322 | border-radius: 2px; 323 | -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.15), 0 1px 3px rgba(0,0,0,0.3); 324 | } 325 | .parallax-layer { 326 | position: absolute; 327 | width: 100%; 328 | height: 100%; 329 | border-bottom-right-radius: 4px; 330 | border-bottom-left-radius: 4px; 331 | } 332 | .para-0 { 333 | background: url(img/bgs/tama.jpg) center center; 334 | } 335 | .para-1 { 336 | background: url(img/para-1.png); 337 | } 338 | .para-2 { 339 | background: url(img/para-2.png); 340 | } 341 | 342 | /* Settings */ 343 | 344 | #settings-ovl { 345 | display: none; 346 | position: absolute; 347 | top: 50px; 348 | left: 0; 349 | right: 0; 350 | bottom: 0px; 351 | background: rgba(0,0,0,0.6); 352 | -webkit-border-bottom-right-radius: 2px; 353 | -webkit-border-bottom-left-radius: 2px; 354 | } 355 | #settings-wrap { 356 | margin: 30px auto 0 auto; 357 | width: 300px; 358 | background: #fff; 359 | -webkit-border-top-left-radius: 2px; 360 | -webkit-border-top-right-radius: 2px; 361 | } 362 | .settings-item { 363 | padding: 15px; 364 | border-bottom: 1px solid #e0e0e0; 365 | } 366 | .settings-item:last-child { 367 | border: 0; 368 | } 369 | .settings-item-left { 370 | float: left; 371 | width: 190px; 372 | } 373 | .settings-item-title { 374 | padding-bottom: 5px; 375 | font-weight: bold; 376 | } 377 | .settings-item-desc { 378 | font-size: 11px; 379 | } 380 | .settings-item-right { 381 | float: right; 382 | } 383 | .settings-item-btn { 384 | cursor: pointer; 385 | width: 60px; 386 | padding: 6px 0; 387 | color: #fff; 388 | font-size: 11px; 389 | /* font-weight: bold; */ 390 | background: #4b99f0; 391 | text-align: center; 392 | -webkit-border-radius: 2px; 393 | } 394 | .settings-item-btn:hover { 395 | opacity: 0.7; 396 | } 397 | #settings-close { 398 | cursor: pointer; 399 | margin: 0 auto; 400 | padding: 15px 0; 401 | width: 300px; 402 | color: #515151; 403 | font-size: 14px; 404 | font-weight: bold; 405 | text-align: center; 406 | background: #e0e0e0; 407 | -webkit-border-bottom-right-radius: 2px; 408 | -webkit-border-bottom-left-radius: 2px; 409 | } 410 | #settings-close:hover { 411 | background: #eee; 412 | } 413 | 414 | #settings-title { 415 | padding-top: 30px; 416 | width: 360px; 417 | color: #fff; 418 | font-size: 23px; 419 | text-align: center; 420 | text-shadow: 0 0 6px rgba(0,0,0,0.6); 421 | } 422 | 423 | 424 | /* Tour */ 425 | 426 | /* Retake */ 427 | 428 | #tour-wrap { 429 | display: none; 430 | overflow: hidden; 431 | position: absolute; 432 | top: 50px; 433 | bottom: 50px; 434 | width: 360px; 435 | } 436 | #tour-slide-wrap { 437 | position: absolute; 438 | width: 1440px; 439 | left: 0; 440 | } 441 | #tour-wrap.hidden { 442 | opacity: 0; 443 | left: -10px; 444 | } 445 | #tour-take { 446 | cursor: pointer; 447 | margin: 250px auto 0 auto; 448 | width: 208px; 449 | color: #fff; 450 | text-align: center; 451 | line-height: 40px; 452 | background: #575d6a; 453 | border-radius: 4px; 454 | } 455 | #tour-take:hover { 456 | opacity: 0.9; 457 | } 458 | #tour-skip { 459 | margin: 0 auto; 460 | padding-top: 30px; 461 | width: 208px; 462 | text-align: center; 463 | } 464 | #tour-text-skip { 465 | cursor: pointer; 466 | } 467 | 468 | .tour-control-wrap { 469 | display: none; 470 | position: absolute; 471 | top: 450px; 472 | left: 50%; 473 | margin-left: -25px; 474 | } 475 | .tour-control-left, .tour-control-right { 476 | cursor: pointer; 477 | float: left; 478 | padding: 5px; 479 | width: 10px; 480 | height: 10px; 481 | border-radius: 2px; 482 | } 483 | .tour-control-left:hover, .tour-control-right:hover { 484 | opacity: 0.9; 485 | } 486 | .tour-control-left { 487 | background: #292c32 url(img/chev-left.png) center center no-repeat; 488 | } 489 | .tour-control-right { 490 | margin-left: 10px; 491 | background: #292c32 url(img/chev-right.png) center center no-repeat; 492 | } 493 | 494 | /* Slide priorities */ 495 | 496 | .tour-slide { 497 | float: left; 498 | width: 360px; 499 | height: 500px; 500 | } 501 | #tour-slide-0 { 502 | z-index: 9999; 503 | background: url(img/tour-bg.png) center center no-repeat; 504 | -webkit-box-shadow: inset 0 -2px 0 rgba(0,0,0,0.15); 505 | } 506 | #tour-slide-1 { 507 | background: url(img/tour-1.png) center center no-repeat; 508 | -webkit-box-shadow: inset 0 -2px 0 rgba(87,93,106,1); 509 | } 510 | #tour-slide-2 { 511 | background: url(img/tour-2.png) center center no-repeat; 512 | -webkit-box-shadow: inset 0 -2px 0 rgba(75,153,240,1); 513 | } 514 | #tour-slide-3 { 515 | background: url(img/tour-3.png) center center no-repeat; 516 | -webkit-box-shadow: inset 0 -2px 0 rgba(236,70,78,1); 517 | } 518 | 519 | /* Activity */ 520 | 521 | .activity { 522 | color: #292c32; 523 | line-height: 1.5em; 524 | /*border-top: 2px solid #a9cef8;*/ 525 | background: #fff url(img/activity/line.png) 34px center repeat-y; 526 | /* -webkit-box-shadow: inset 0 -4px 0 #fff, inset 0 4px 0 #fff; */ 527 | } 528 | .activity-icon-wrap { 529 | float: left; 530 | padding: 20px 15px 0 15px; 531 | width: 40px; 532 | height: 40px; 533 | } 534 | .activity-icon { 535 | width: 40px; 536 | height: 40px; 537 | background-color: #e0e0e0; 538 | background-position: center center; 539 | background-repeat: no-repeat; 540 | -webkit-border-radius: 40px; 541 | -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.6), 0 4px 0 #fff, 0 -4px 0 #fff; 542 | } 543 | .activity-icon-ovl { 544 | 545 | } 546 | .activity-right { 547 | float: right; 548 | padding: 15px 15px 15px 0; 549 | width: 270px; 550 | } 551 | .activity:last-child { 552 | border-bottom: none; 553 | } 554 | .activity.connected { 555 | background-image: url(img/activity/connect.png); 556 | background-position: 15px center; 557 | background-repeat: no-repeat; 558 | } 559 | .activity-timeago { 560 | color: #89909e; 561 | font-size: 11px; 562 | } 563 | .activity-actor { 564 | font-weight: bold; 565 | } 566 | .activity-object { 567 | font-weight: bold; 568 | } 569 | 570 | /* Sub activity */ 571 | 572 | .sub-activity-list { 573 | background: #eef5fc url(img/activity/line.png) 34px center repeat-y; 574 | /*-webkit-box-shadow: inset 0 -4px 0 #eef5fc, inset 0 4px 0 #eef5fc;*/ 575 | } 576 | .sub-activity { 577 | padding: 10px 15px 10px 31px; 578 | color: #575d6a; 579 | line-height: 1.5em; 580 | /* -webkit-box-shadow: inset 0 -4px 0 #eef5fc, inset 0 4px 0 #eef5fc; */ 581 | } 582 | .sub-activity-icon { 583 | margin-top: 5px; 584 | float: left; 585 | width: 4px; 586 | height: 4px; 587 | border: 2px solid #a9cef8; 588 | background: #eef5fc; 589 | -webkit-border-radius: 14px; 590 | -webkit-box-shadow: 0 4px 0 #eef5fc, 0 -4px 0 #eef5fc; 591 | } 592 | .sub-activity-right { 593 | float: right; 594 | width: 270px; 595 | } 596 | .sub-activity-timeago { 597 | color: #89909e; 598 | font-size: 11px; 599 | } 600 | .sub-activity-object { 601 | font-weight: bold; 602 | } -------------------------------------------------------------------------------- /default.min.css: -------------------------------------------------------------------------------- 1 | html{color:#000;background:#FFF}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}input,textarea,select{*font-size:100%}legend{color:#000}#yui3-css-stamp.cssreset{display:none}@font-face{font-family:'open_sansbold';src:url('font/OpenSans-Bold-webfont.woff') format('woff'),url('font/OpenSans-Bold-webfont.ttf') format('truetype');font-weight:normal;font-style:normal}@font-face{font-family:'open_sanslight';src:url('font/OpenSans-Light-webfont.woff') format('woff'),url('font/OpenSans-Light-webfont.ttf') format('truetype');font-weight:normal;font-style:normal}@font-face{font-family:'open_sansregular';src:url('font/OpenSans-Regular-webfont.woff') format('woff'),url('font/OpenSans-Regular-webfont.ttf') format('truetype');font-weight:normal;font-style:normal}@font-face{font-family:'open_sanssemibold';src:url('font/OpenSans-Semibold-webfont.woff') format('woff'),url('font/OpenSans-Semibold-webfont.ttf') format('truetype');font-weight:normal;font-style:normal}.openbold{font-family:'open_sansbold',sans-serif}.openlight{font-family:'open_sanslight',sans-serif}.openregular{font-family:'open_sansregular',sans-serif}.opensemi{font-family:'open_sanssemibold',sans-serif}.cf:before,.cf:after{content:" ";display:table}.cf:after{clear:both}.ts{-webkit-transition:.1s ease all}.ts2{-webkit-transition:.5s ease all}.ns{-webkit-user-select:none}#loading{opacity:0;position:absolute;bottom:-50px;left:69px;margin-top:1px;padding-left:31px;height:49px;line-height:49px;color:#89909e;background:#292c32 url(img/4.gif) center left no-repeat}#loading.visible{opacity:1;bottom:0}html{-webkit-transform:translateZ(0);padding-top:14px;width:388px;height:614px;background:url(img/app-shadow-darker.png) center center no-repeat}body{overflow:hidden;margin:0 auto;width:360px;height:600px;font-size:13px;font-family:'Helvetica Neue','Helvetica',arial,sans-serif;background:#fff;border-radius:4px;border-top-left-radius:8px;border-top-right-radius:8px}a,a:visited{color:#4b99f0;text-decoration:none}a:hover{text-decoration:underline}#app-wrap{overflow:hidden;position:relative}#top{cursor:default;overflow:hidden;position:relative;height:50px;background:#292c32;border-top-left-radius:4px;border-top-right-radius:4px;-webkit-box-shadow:inset 0 1px 0 #34373c}#top-user{float:left;padding-left:15px;height:50px;color:#fff;line-height:50px;border-left:1px solid #34373c}#top-logo{float:left;padding:0 15px;width:23px;height:50px;border-right:1px solid rgba(0,0,0,0.2);background:url(img/hb-mini.png) center center no-repeat}#top-controls{float:right}#top-minimize{float:left;margin:17px 17px 0 0;width:16px;height:16px;background:url(img/top-minimize.png) center center no-repeat}#top-close{float:left;margin:17px 17px 0 0;width:16px;height:16px;background:url(img/top-close.png) center center no-repeat}#top-close:hover,#top-minimize:hover{cursor:pointer;opacity:.7}#middle{overflow-x:hidden;overflow-y:scroll;height:500px;background-color:#eef5fc;background-repeat:no-repeat;background-position:center center;background-image:url(img/bgs/main-bg-w.png)}#middle.new{background-image:url(img/tour-4.png)}#middle::-webkit-scrollbar{width:5px;height:5px}#middle::-webkit-scrollbar-button{display:none}#middle::-webkit-scrollbar-track-piece{background:transparent}#middle::-webkit-scrollbar-thumb{background:rgba(0,0,0,0.3);border-radius:0}#middle::-webkit-scrollbar-track{padding:2px;background:rgba(0,0,0,0.2);border-radius:0}#middle::-webkit-scrollbar-button:start:decrement{display:block;height:0}#middle::-webkit-scrollbar-button:end:increment{display:block;height:0}#bottom{border-top:2px solid transparent;height:50px;background:#fff;border-bottom-right-radius:4px;border-bottom-left-radius:4px}#bottom.toured{border-top:2px solid #4b99f0}.bottom-menu-item{cursor:pointer;float:left;padding:0 15px 0 43px;width:121px;color:#515151;font-size:14px;font-weight:bold;line-height:50px;border-right:1px solid #e0e0e0;text-decoration:none;text-align:left;background-position:15px center;background-repeat:no-repeat}.bottom-menu-item:hover{opacity:.7;text-decoration:none}.bottom-menu-item:last-child{margin:0;border-right:0}#open-herro{background-image:url(img/middle-open.png)}#open-tour{background-image:url(img/tour.png)}#open-settings{background-image:url(img/settings.png)}#login-form-wrap{display:none;overflow:hidden;position:absolute;top:50px;left:0;right:0;bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}#login-form-ovl{position:relative;z-index:100;height:100%;background:rgba(0,0,0,0.3);border-bottom-right-radius:4px;border-bottom-left-radius:4px}#login-form-logo{width:360px;height:250px;background:url(img/login-logo-text.png) center center no-repeat}.login-form-section{padding-bottom:15px;text-align:center}.login-form-input{outline:0;padding:11px;width:270px;font-size:14px;border-radius:2px;background:#e0e0e0;border:0;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.3)}.login-form-input:focus{background:#fff;-webkit-box-shadow:none}.login-form-about{padding-top:72px;color:#cfcfcf;font-size:11px;text-align:center;line-height:2em;text-shadow:0 1px 0 rgba(0,0,0,0.3)}#login-form-submit{cursor:pointer;margin:0 0 15px 35px;padding:10px 0;width:290px;color:#fff;text-align:center;text-transform:uppercase;background:#4b99f0;border-radius:2px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 3px rgba(0,0,0,0.3)}.parallax-layer{position:absolute;width:100%;height:100%;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.para-0{background:url(img/bgs/tama.jpg) center center}.para-1{background:url(img/para-1.png)}.para-2{background:url(img/para-2.png)}#settings-ovl{display:none;position:absolute;top:50px;left:0;right:0;bottom:0;background:rgba(0,0,0,0.6);-webkit-border-bottom-right-radius:2px;-webkit-border-bottom-left-radius:2px}#settings-wrap{margin:30px auto 0 auto;width:300px;background:#fff;-webkit-border-top-left-radius:2px;-webkit-border-top-right-radius:2px}.settings-item{padding:15px;border-bottom:1px solid #e0e0e0}.settings-item:last-child{border:0}.settings-item-left{float:left;width:190px}.settings-item-title{padding-bottom:5px;font-weight:bold}.settings-item-desc{font-size:11px}.settings-item-right{float:right}.settings-item-btn{cursor:pointer;width:60px;padding:6px 0;color:#fff;font-size:11px;background:#4b99f0;text-align:center;-webkit-border-radius:2px}.settings-item-btn:hover{opacity:.7}#settings-close{cursor:pointer;margin:0 auto;padding:15px 0;width:300px;color:#515151;font-size:14px;font-weight:bold;text-align:center;background:#e0e0e0;-webkit-border-bottom-right-radius:2px;-webkit-border-bottom-left-radius:2px}#settings-close:hover{background:#eee}#settings-title{padding-top:30px;width:360px;color:#fff;font-size:23px;text-align:center;text-shadow:0 0 6px rgba(0,0,0,0.6)}#tour-wrap{display:none;overflow:hidden;position:absolute;top:50px;bottom:50px;width:360px}#tour-slide-wrap{position:absolute;width:1440px;left:0}#tour-wrap.hidden{opacity:0;left:-10px}#tour-take{cursor:pointer;margin:250px auto 0 auto;width:208px;color:#fff;text-align:center;line-height:40px;background:#575d6a;border-radius:4px}#tour-take:hover{opacity:.9}#tour-skip{margin:0 auto;padding-top:30px;width:208px;text-align:center}#tour-text-skip{cursor:pointer}.tour-control-wrap{display:none;position:absolute;top:450px;left:50%;margin-left:-25px}.tour-control-left,.tour-control-right{cursor:pointer;float:left;padding:5px;width:10px;height:10px;border-radius:2px}.tour-control-left:hover,.tour-control-right:hover{opacity:.9}.tour-control-left{background:#292c32 url(img/chev-left.png) center center no-repeat}.tour-control-right{margin-left:10px;background:#292c32 url(img/chev-right.png) center center no-repeat}.tour-slide{float:left;width:360px;height:500px}#tour-slide-0{z-index:9999;background:url(img/tour-bg.png) center center no-repeat;-webkit-box-shadow:inset 0 -2px 0 rgba(0,0,0,0.15)}#tour-slide-1{background:url(img/tour-1.png) center center no-repeat;-webkit-box-shadow:inset 0 -2px 0 rgba(87,93,106,1)}#tour-slide-2{background:url(img/tour-2.png) center center no-repeat;-webkit-box-shadow:inset 0 -2px 0 rgba(75,153,240,1)}#tour-slide-3{background:url(img/tour-3.png) center center no-repeat;-webkit-box-shadow:inset 0 -2px 0 rgba(236,70,78,1)}.activity{color:#292c32;line-height:1.5em;background:#fff url(img/activity/line.png) 34px center repeat-y}.activity-icon-wrap{float:left;padding:20px 15px 0 15px;width:40px;height:40px}.activity-icon{width:40px;height:40px;background-color:#e0e0e0;background-position:center center;background-repeat:no-repeat;-webkit-border-radius:40px;-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6),0 4px 0 #fff,0 -4px 0 #fff}.activity-right{float:right;padding:15px 15px 15px 0;width:270px}.activity:last-child{border-bottom:0}.activity.connected{background-image:url(img/activity/connect.png);background-position:15px center;background-repeat:no-repeat}.activity-timeago{color:#89909e;font-size:11px}.activity-actor{font-weight:bold}.activity-object{font-weight:bold}.sub-activity-list{background:#eef5fc url(img/activity/line.png) 34px center repeat-y}.sub-activity{padding:10px 15px 10px 31px;color:#575d6a;line-height:1.5em}.sub-activity-icon{margin-top:5px;float:left;width:4px;height:4px;border:2px solid #a9cef8;background:#eef5fc;-webkit-border-radius:14px;-webkit-box-shadow:0 4px 0 #eef5fc,0 -4px 0 #eef5fc}.sub-activity-right{float:right;width:270px}.sub-activity-timeago{color:#89909e;font-size:11px}.sub-activity-object{font-weight:bold} -------------------------------------------------------------------------------- /detect.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | :detectAnime 3 | tasklist /v /fo:list | findstr ".avi .mkv .mp4" 4 | ping 1.1.1.1 -n 1 -w 1000 >nul 5 | cls > nul 6 | goto detectAnime -------------------------------------------------------------------------------- /font/OpenSans-Bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/font/OpenSans-Bold-webfont.ttf -------------------------------------------------------------------------------- /font/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/font/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /font/OpenSans-Light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/font/OpenSans-Light-webfont.ttf -------------------------------------------------------------------------------- /font/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/font/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /font/OpenSans-Regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/font/OpenSans-Regular-webfont.ttf -------------------------------------------------------------------------------- /font/OpenSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/font/OpenSans-Regular-webfont.woff -------------------------------------------------------------------------------- /font/OpenSans-Semibold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/font/OpenSans-Semibold-webfont.ttf -------------------------------------------------------------------------------- /font/OpenSans-Semibold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/font/OpenSans-Semibold-webfont.woff -------------------------------------------------------------------------------- /img/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/128x128.png -------------------------------------------------------------------------------- /img/16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/16x16.png -------------------------------------------------------------------------------- /img/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/32x32.png -------------------------------------------------------------------------------- /img/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/4.gif -------------------------------------------------------------------------------- /img/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/48x48.png -------------------------------------------------------------------------------- /img/activity/connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/activity/connect.png -------------------------------------------------------------------------------- /img/activity/detected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/activity/detected.png -------------------------------------------------------------------------------- /img/activity/line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/activity/line.png -------------------------------------------------------------------------------- /img/activity/scrobbled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/activity/scrobbled.png -------------------------------------------------------------------------------- /img/app-shadow-darker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/app-shadow-darker.png -------------------------------------------------------------------------------- /img/app-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/app-shadow.png -------------------------------------------------------------------------------- /img/bgs/kuma.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/bgs/kuma.jpg -------------------------------------------------------------------------------- /img/bgs/login-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/bgs/login-bg.png -------------------------------------------------------------------------------- /img/bgs/main-bg-w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/bgs/main-bg-w.png -------------------------------------------------------------------------------- /img/bgs/main-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/bgs/main-bg.png -------------------------------------------------------------------------------- /img/bgs/sombrero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/bgs/sombrero.png -------------------------------------------------------------------------------- /img/bgs/tama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/bgs/tama.jpg -------------------------------------------------------------------------------- /img/chev-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/chev-left.png -------------------------------------------------------------------------------- /img/chev-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/chev-right.png -------------------------------------------------------------------------------- /img/guide-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/guide-bg.png -------------------------------------------------------------------------------- /img/hb-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/hb-mini.png -------------------------------------------------------------------------------- /img/herro-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/herro-mini.png -------------------------------------------------------------------------------- /img/icon-popout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/icon-popout.png -------------------------------------------------------------------------------- /img/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/loading.png -------------------------------------------------------------------------------- /img/login-logo-h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/login-logo-h.png -------------------------------------------------------------------------------- /img/login-logo-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/login-logo-text.png -------------------------------------------------------------------------------- /img/login-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/login-logo.png -------------------------------------------------------------------------------- /img/middle-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/middle-open.png -------------------------------------------------------------------------------- /img/nicons/check.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/nicons/check.jpg -------------------------------------------------------------------------------- /img/nicons/scrobble.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/nicons/scrobble.jpg -------------------------------------------------------------------------------- /img/nicons/update.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/nicons/update.jpg -------------------------------------------------------------------------------- /img/note-gloss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/note-gloss.png -------------------------------------------------------------------------------- /img/note.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/note.png -------------------------------------------------------------------------------- /img/note_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/note_2.png -------------------------------------------------------------------------------- /img/para-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/para-1.png -------------------------------------------------------------------------------- /img/para-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/para-2.png -------------------------------------------------------------------------------- /img/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/settings.png -------------------------------------------------------------------------------- /img/top-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/top-bg.png -------------------------------------------------------------------------------- /img/top-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/top-close.png -------------------------------------------------------------------------------- /img/top-minimize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/top-minimize.png -------------------------------------------------------------------------------- /img/tour-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/tour-1.png -------------------------------------------------------------------------------- /img/tour-2-old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/tour-2-old.png -------------------------------------------------------------------------------- /img/tour-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/tour-2.png -------------------------------------------------------------------------------- /img/tour-3-old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/tour-3-old.png -------------------------------------------------------------------------------- /img/tour-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/tour-3.png -------------------------------------------------------------------------------- /img/tour-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/tour-4.png -------------------------------------------------------------------------------- /img/tour-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/tour-bg.png -------------------------------------------------------------------------------- /img/tour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tofuness/Hummingbird-Updater/4158bf8ad79d8abc01e2b69db3bf79ca10740a10/img/tour.png -------------------------------------------------------------------------------- /js/AIRAliases.js: -------------------------------------------------------------------------------- 1 | /* AIRAliases.js - Revision: 2.5 */ 2 | 3 | /* 4 | ADOBE SYSTEMS INCORPORATED 5 | Copyright 2007-2009 Adobe Systems Incorporated. All Rights Reserved. 6 | 7 | NOTICE: Adobe permits you to modify and distribute this file only in accordance with 8 | the terms of Adobe AIR SDK license agreement. You may have received this file from a 9 | source other than Adobe. Nonetheless, you may modify or 10 | distribute this file only in accordance with such agreement. 11 | */ 12 | 13 | 14 | var air; 15 | if (window.runtime) 16 | { 17 | if (!air) air = {}; 18 | // workers 19 | air.Worker = window.runtime.flash.system.Worker; 20 | air.WorkerDomain = window.runtime.flash.system.WorkerDomain; 21 | air.WorkerState = window.runtime.flash.system.WorkerState; 22 | air.MessageChannelState = window.runtime.flash.system.MessageChannelState; 23 | air.Condition = window.runtime.flash.concurrent.Condition; 24 | air.Mutex = window.runtime.flash.concurrent.Mutex; 25 | 26 | // functions 27 | air.trace = window.runtime.trace; 28 | air.navigateToURL = window.runtime.flash.net.navigateToURL; 29 | air.sendToURL = window.runtime.flash.net.sendToURL; 30 | 31 | 32 | // file 33 | air.File = window.runtime.flash.filesystem.File; 34 | air.FileStream = window.runtime.flash.filesystem.FileStream; 35 | air.FileMode = window.runtime.flash.filesystem.FileMode; 36 | 37 | air.StorageVolumeInfo = window.runtime.flash.filesystem.StorageVolumeInfo; 38 | 39 | // events 40 | air.ActivityEvent = window.runtime.flash.events.ActivityEvent; 41 | air.AsyncErrorEvent = window.runtime.flash.events.AsyncErrorEvent; 42 | air.BrowserInvokeEvent = window.runtime.flash.events.BrowserInvokeEvent; 43 | air.DataEvent = window.runtime.flash.events.DataEvent; 44 | air.DRMAuthenticateEvent = window.runtime.flash.events.DRMAuthenticateEvent; 45 | air.DRMStatusEvent = window.runtime.flash.events.DRMStatusEvent; 46 | air.ErrorEvent = window.runtime.flash.events.ErrorEvent; 47 | air.Event = window.runtime.flash.events.Event; 48 | air.EventDispatcher = window.runtime.flash.events.EventDispatcher; 49 | air.FileListEvent = window.runtime.flash.events.FileListEvent; 50 | air.HTTPStatusEvent = window.runtime.flash.events.HTTPStatusEvent; 51 | air.IOErrorEvent = window.runtime.flash.events.IOErrorEvent; 52 | air.InvokeEvent = window.runtime.flash.events.InvokeEvent; 53 | air.InvokeEventReason = window.runtime.flash.desktop.InvokeEventReason; 54 | air.NetStatusEvent = window.runtime.flash.events.NetStatusEvent; 55 | air.OutputProgressEvent = window.runtime.flash.events.OutputProgressEvent; 56 | air.ProgressEvent = window.runtime.flash.events.ProgressEvent; 57 | air.SecurityErrorEvent = window.runtime.flash.events.SecurityErrorEvent; 58 | air.StatusEvent = window.runtime.flash.events.StatusEvent; 59 | air.TimerEvent = window.runtime.flash.events.TimerEvent; 60 | air.SampleDataEvent = window.runtime.flash.events.SampleDataEvent; 61 | air.DatagramSocketDataEvent = window.runtime.flash.events.DatagramSocketDataEvent; 62 | air.DNSResolverEvent = window.runtime.flash.events.DNSResolverEvent; 63 | air.ServerSocketConnectEvent = window.runtime.flash.events.ServerSocketConnectEvent; 64 | air.StorageVolumeChangeEvent = window.runtime.flash.events.StorageVolumeChangeEvent; 65 | air.NativeProcessExitEvent = window.runtime.flash.events.NativeProcessExitEvent; 66 | air.UncaughtErrorEvent = window.runtime.flash.events.UncaughtErrorEvent; 67 | air.MouseEvent = window.runtime.flash.events.MouseEvent; 68 | 69 | // native window 70 | air.NativeWindow = window.runtime.flash.display.NativeWindow; 71 | air.NativeWindowDisplayState = window.runtime.flash.display.NativeWindowDisplayState; 72 | air.NativeWindowInitOptions = window.runtime.flash.display.NativeWindowInitOptions; 73 | air.NativeWindowSystemChrome = window.runtime.flash.display.NativeWindowSystemChrome; 74 | air.NativeWindowResize = window.runtime.flash.display.NativeWindowResize; 75 | air.NativeWindowType = window.runtime.flash.display.NativeWindowType; 76 | 77 | air.NativeWindowBoundsEvent = window.runtime.flash.events.NativeWindowBoundsEvent; 78 | air.NativeWindowDisplayStateEvent = window.runtime.flash.events.NativeWindowDisplayStateEvent; 79 | 80 | // geom 81 | air.Point = window.runtime.flash.geom.Point; 82 | air.Rectangle = window.runtime.flash.geom.Rectangle; 83 | air.Matrix = window.runtime.flash.geom.Matrix; 84 | 85 | // 3D 86 | air.Matrix3D = window.runtime.flash.geom.Matrix3D; 87 | air.Vector3D = window.runtime.flash.geom.Vector3D; 88 | air.Orientation3D = window.runtime.flash.geom.Orientation3D; 89 | air.Utils3D = window.runtime.flash.geom.Utils3D; 90 | 91 | // Shader 92 | air.Shader = window.runtime.flash.display.Shader; 93 | air.ShaderFilter = window.runtime.flash.filters.ShaderFilter; 94 | air.ShaderPrecision = window.runtime.flash.display.ShaderPrecision; 95 | 96 | // net 97 | air.FileFilter = window.runtime.flash.net.FileFilter; 98 | 99 | air.LocalConnection = window.runtime.flash.net.LocalConnection; 100 | air.NetConnection = window.runtime.flash.net.NetConnection; 101 | 102 | air.URLLoader = window.runtime.flash.net.URLLoader; 103 | air.URLLoaderDataFormat = window.runtime.flash.net.URLLoaderDataFormat; 104 | air.URLRequest = window.runtime.flash.net.URLRequest; 105 | air.URLRequestDefaults = window.runtime.flash.net.URLRequestDefaults; 106 | air.URLRequestHeader = window.runtime.flash.net.URLRequestHeader; 107 | air.URLRequestMethod = window.runtime.flash.net.URLRequestMethod; 108 | air.URLStream = window.runtime.flash.net.URLStream; 109 | air.URLVariables = window.runtime.flash.net.URLVariables; 110 | air.Socket = window.runtime.flash.net.Socket; 111 | air.XMLSocket = window.runtime.flash.net.XMLSocket; 112 | 113 | air.SecureSocket = window.runtime.flash.net.SecureSocket; 114 | air.CertificateStatus = window.runtime.flash.security.CertificateStatus; 115 | 116 | air.Responder = window.runtime.flash.net.Responder; 117 | air.ObjectEncoding = window.runtime.flash.net.ObjectEncoding; 118 | 119 | air.NetStream = window.runtime.flash.net.NetStream; 120 | air.NetStreamInfo = window.runtime.flash.net.NetStreamInfo; 121 | air.NetStreamPlayOptions = window.runtime.flash.net.NetStreamPlayOptions; 122 | air.NetStreamPlayTransitions = window.runtime.flash.net.NetStreamPlayTransitions; 123 | air.SharedObject = window.runtime.flash.net.SharedObject; 124 | air.SharedObjectFlushStatus = window.runtime.flash.net.SharedObjectFlushStatus; 125 | 126 | air.DatagramSocket = window.runtime.flash.net.DatagramSocket; 127 | air.NetworkInfo = window.runtime.flash.net.NetworkInfo; 128 | air.ServerSocket = window.runtime.flash.net.ServerSocket; 129 | air.IPVersion = window.runtime.flash.net.IPVersion; 130 | 131 | air.DNSResolver = window.runtime.flash.net.dns.DNSResolver; 132 | air.ARecord = window.runtime.flash.net.dns.ARecord; 133 | air.AAAARecord = window.runtime.flash.net.dns.AAAARecord; 134 | air.MXRecord = window.runtime.flash.net.dns.MXRecord; 135 | air.PTRRecord = window.runtime.flash.net.dns.PTRRecord; 136 | air.SRVRecord = window.runtime.flash.net.dns.SRVRecord; 137 | 138 | // system 139 | air.Capabilities = window.runtime.flash.system.Capabilities; 140 | air.System = window.runtime.flash.system.System; 141 | air.Security = window.runtime.flash.system.Security; 142 | air.Updater = window.runtime.flash.desktop.Updater; 143 | 144 | // desktop 145 | air.Clipboard = window.runtime.flash.desktop.Clipboard; 146 | air.ClipboardFormats = window.runtime.flash.desktop.ClipboardFormats; 147 | air.ClipboardTransferMode = window.runtime.flash.desktop.ClipboardTransferMode; 148 | 149 | air.NativeDragManager = window.runtime.flash.desktop.NativeDragManager; 150 | air.NativeDragOptions = window.runtime.flash.desktop.NativeDragOptions; 151 | air.NativeDragActions = window.runtime.flash.desktop.NativeDragActions; 152 | 153 | air.Icon = window.runtime.flash.desktop.Icon; 154 | air.DockIcon = window.runtime.flash.desktop.DockIcon; 155 | air.InteractiveIcon = window.runtime.flash.desktop.InteractiveIcon; 156 | air.NotificationType = window.runtime.flash.desktop.NotificationType; 157 | air.SystemTrayIcon = window.runtime.flash.desktop.SystemTrayIcon; 158 | 159 | air.NativeApplication = window.runtime.flash.desktop.NativeApplication; 160 | 161 | air.NativeProcess = window.runtime.flash.desktop.NativeProcess; 162 | air.NativeProcessStartupInfo = window.runtime.flash.desktop.NativeProcessStartupInfo; 163 | 164 | // display 165 | air.NativeMenu = window.runtime.flash.display.NativeMenu; 166 | air.NativeMenuItem = window.runtime.flash.display.NativeMenuItem; 167 | air.Screen = window.runtime.flash.display.Screen; 168 | 169 | air.Loader = window.runtime.flash.display.Loader; 170 | air.Bitmap = window.runtime.flash.display.Bitmap; 171 | air.BitmapData = window.runtime.flash.display.BitmapData; 172 | 173 | // ui 174 | air.Keyboard = window.runtime.flash.ui.Keyboard; 175 | air.KeyLocation = window.runtime.flash.ui.KeyLocation; 176 | air.Mouse = window.runtime.flash.ui.Mouse; 177 | 178 | 179 | //security 180 | air.ReferencesValidationSetting = window.runtime.flash.security.ReferencesValidationSetting; 181 | air.RevocationCheckSettings = window.runtime.flash.security.RevocationCheckSettings; 182 | air.SignatureStatus = window.runtime.flash.security.SignatureStatus; 183 | air.SignerTrustSettings = window.runtime.flash.security.SignerTrustSettings; 184 | air.XMLSignatureValidator = window.runtime.flash.security.XMLSignatureValidator; 185 | 186 | 187 | // utils 188 | air.ByteArray = window.runtime.flash.utils.ByteArray; 189 | air.CompressionAlgorithm = window.runtime.flash.utils.CompressionAlgorithm; 190 | air.Endian = window.runtime.flash.utils.Endian; 191 | air.Timer = window.runtime.flash.utils.Timer; 192 | air.IDataInput = window.runtime.flash.utils.IDataInput; 193 | air.IDataOutput = window.runtime.flash.utils.IDataOutput; 194 | 195 | air.HTMLLoader = window.runtime.flash.html.HTMLLoader; 196 | air.HTMLPDFCapability = window.runtime.flash.html.HTMLPDFCapability; 197 | 198 | air.Vector = window.runtime.Vector; 199 | 200 | // media 201 | air.ID3Info = window.runtime.flash.media.ID3Info; 202 | air.Sound = window.runtime.flash.media.Sound; 203 | air.SoundChannel = window.runtime.flash.media.SoundChannel; 204 | air.SoundLoaderContext = window.runtime.flash.media.SoundLoaderContext; 205 | air.SoundMixer = window.runtime.flash.media.SoundMixer; 206 | air.SoundTransform = window.runtime.flash.media.SoundTransform; 207 | air.Microphone = window.runtime.flash.media.Microphone; 208 | air.Video = window.runtime.flash.media.Video; 209 | air.Camera = window.runtime.flash.media.Camera; 210 | air.SoundCodec = window.runtime.flash.media.SoundCodec; 211 | 212 | // data 213 | air.EncryptedLocalStore = window.runtime.flash.data.EncryptedLocalStore; 214 | air.SQLCollationType = window.runtime.flash.data.SQLCollationType; 215 | air.SQLColumnNameStyle = window.runtime.flash.data.SQLColumnNameStyle; 216 | air.SQLColumnSchema = window.runtime.flash.data.SQLColumnSchema; 217 | air.SQLConnection = window.runtime.flash.data.SQLConnection; 218 | air.SQLError = window.runtime.flash.errors.SQLError; 219 | air.SQLErrorEvent = window.runtime.flash.events.SQLErrorEvent; 220 | air.SQLErrorOperation = window.runtime.flash.errors.SQLErrorOperation; 221 | air.SQLEvent = window.runtime.flash.events.SQLEvent; 222 | air.SQLIndexSchema = window.runtime.flash.data.SQLIndexSchema; 223 | air.SQLMode = window.runtime.flash.data.SQLMode; 224 | air.SQLResult = window.runtime.flash.data.SQLResult; 225 | air.SQLSchema = window.runtime.flash.data.SQLSchema; 226 | air.SQLSchemaResult = window.runtime.flash.data.SQLSchemaResult; 227 | air.SQLStatement = window.runtime.flash.data.SQLStatement; 228 | air.SQLTableSchema = window.runtime.flash.data.SQLTableSchema; 229 | air.SQLTransactionLockType = window.runtime.flash.data.SQLTransactionLockType; 230 | air.SQLTriggerSchema = window.runtime.flash.data.SQLTriggerSchema; 231 | air.SQLUpdateEvent = window.runtime.flash.events.SQLUpdateEvent; 232 | air.SQLViewSchema = window.runtime.flash.data.SQLViewSchema; 233 | 234 | // core framework 235 | air.__defineGetter__("ServiceMonitor", function() { return window.runtime.air.net.ServiceMonitor; }); 236 | air.__defineGetter__("SocketMonitor", function() { return window.runtime.air.net.SocketMonitor; }); 237 | air.__defineGetter__("URLMonitor", function() { return window.runtime.air.net.URLMonitor; }); 238 | air.__defineGetter__("SecureSocketMonitor", function() { return window.runtime.air.net.SecureSocketMonitor; }); 239 | air.__defineGetter__("URLFilePromise", function() { return window.runtime.air.desktop.URLFilePromise; }); 240 | 241 | // update framework 242 | air.__defineGetter__("ApplicationUpdater", function() { return window.runtime.air.update.ApplicationUpdater; }); 243 | air.__defineGetter__("ApplicationUpdaterUI", function() { return window.runtime.air.update.ApplicationUpdaterUI; }); 244 | air.__defineGetter__("UpdateEvent", function() { return window.runtime.air.update.events.UpdateEvent; }); 245 | air.__defineGetter__("StatusUpdateEvent", function() { return window.runtime.air.update.events.StatusUpdateEvent; }); 246 | air.__defineGetter__("StatusUpdateErrorEvent", function() { return window.runtime.air.update.events.StatusUpdateErrorEvent; }); 247 | air.__defineGetter__("DownloadErrorEvent", function() { return window.runtime.air.update.events.DownloadErrorEvent; }); 248 | air.__defineGetter__("StatusFileUpdateEvent", function() { return window.runtime.air.update.events.StatusFileUpdateEvent; }); 249 | air.__defineGetter__("StatusFileUpdateErrorEvent", function() { return window.runtime.air.update.events.StatusFileUpdateErrorEvent; }); 250 | } 251 | -------------------------------------------------------------------------------- /js/AIRAliases.min.js: -------------------------------------------------------------------------------- 1 | var air;window.runtime&&(air||(air={}),air.Worker=window.runtime.flash.system.Worker,air.WorkerDomain=window.runtime.flash.system.WorkerDomain,air.WorkerState=window.runtime.flash.system.WorkerState,air.MessageChannelState=window.runtime.flash.system.MessageChannelState,air.Condition=window.runtime.flash.concurrent.Condition,air.Mutex=window.runtime.flash.concurrent.Mutex,air.trace=window.runtime.trace,air.navigateToURL=window.runtime.flash.net.navigateToURL,air.sendToURL=window.runtime.flash.net.sendToURL,air.File=window.runtime.flash.filesystem.File,air.FileStream=window.runtime.flash.filesystem.FileStream,air.FileMode=window.runtime.flash.filesystem.FileMode,air.StorageVolumeInfo=window.runtime.flash.filesystem.StorageVolumeInfo,air.ActivityEvent=window.runtime.flash.events.ActivityEvent,air.AsyncErrorEvent=window.runtime.flash.events.AsyncErrorEvent,air.BrowserInvokeEvent=window.runtime.flash.events.BrowserInvokeEvent,air.DataEvent=window.runtime.flash.events.DataEvent,air.DRMAuthenticateEvent=window.runtime.flash.events.DRMAuthenticateEvent,air.DRMStatusEvent=window.runtime.flash.events.DRMStatusEvent,air.ErrorEvent=window.runtime.flash.events.ErrorEvent,air.Event=window.runtime.flash.events.Event,air.EventDispatcher=window.runtime.flash.events.EventDispatcher,air.FileListEvent=window.runtime.flash.events.FileListEvent,air.HTTPStatusEvent=window.runtime.flash.events.HTTPStatusEvent,air.IOErrorEvent=window.runtime.flash.events.IOErrorEvent,air.InvokeEvent=window.runtime.flash.events.InvokeEvent,air.InvokeEventReason=window.runtime.flash.desktop.InvokeEventReason,air.NetStatusEvent=window.runtime.flash.events.NetStatusEvent,air.OutputProgressEvent=window.runtime.flash.events.OutputProgressEvent,air.ProgressEvent=window.runtime.flash.events.ProgressEvent,air.SecurityErrorEvent=window.runtime.flash.events.SecurityErrorEvent,air.StatusEvent=window.runtime.flash.events.StatusEvent,air.TimerEvent=window.runtime.flash.events.TimerEvent,air.SampleDataEvent=window.runtime.flash.events.SampleDataEvent,air.DatagramSocketDataEvent=window.runtime.flash.events.DatagramSocketDataEvent,air.DNSResolverEvent=window.runtime.flash.events.DNSResolverEvent,air.ServerSocketConnectEvent=window.runtime.flash.events.ServerSocketConnectEvent,air.StorageVolumeChangeEvent=window.runtime.flash.events.StorageVolumeChangeEvent,air.NativeProcessExitEvent=window.runtime.flash.events.NativeProcessExitEvent,air.UncaughtErrorEvent=window.runtime.flash.events.UncaughtErrorEvent,air.MouseEvent=window.runtime.flash.events.MouseEvent,air.NativeWindow=window.runtime.flash.display.NativeWindow,air.NativeWindowDisplayState=window.runtime.flash.display.NativeWindowDisplayState,air.NativeWindowInitOptions=window.runtime.flash.display.NativeWindowInitOptions,air.NativeWindowSystemChrome=window.runtime.flash.display.NativeWindowSystemChrome,air.NativeWindowResize=window.runtime.flash.display.NativeWindowResize,air.NativeWindowType=window.runtime.flash.display.NativeWindowType,air.NativeWindowBoundsEvent=window.runtime.flash.events.NativeWindowBoundsEvent,air.NativeWindowDisplayStateEvent=window.runtime.flash.events.NativeWindowDisplayStateEvent,air.Point=window.runtime.flash.geom.Point,air.Rectangle=window.runtime.flash.geom.Rectangle,air.Matrix=window.runtime.flash.geom.Matrix,air.Matrix3D=window.runtime.flash.geom.Matrix3D,air.Vector3D=window.runtime.flash.geom.Vector3D,air.Orientation3D=window.runtime.flash.geom.Orientation3D,air.Utils3D=window.runtime.flash.geom.Utils3D,air.Shader=window.runtime.flash.display.Shader,air.ShaderFilter=window.runtime.flash.filters.ShaderFilter,air.ShaderPrecision=window.runtime.flash.display.ShaderPrecision,air.FileFilter=window.runtime.flash.net.FileFilter,air.LocalConnection=window.runtime.flash.net.LocalConnection,air.NetConnection=window.runtime.flash.net.NetConnection,air.URLLoader=window.runtime.flash.net.URLLoader,air.URLLoaderDataFormat=window.runtime.flash.net.URLLoaderDataFormat,air.URLRequest=window.runtime.flash.net.URLRequest,air.URLRequestDefaults=window.runtime.flash.net.URLRequestDefaults,air.URLRequestHeader=window.runtime.flash.net.URLRequestHeader,air.URLRequestMethod=window.runtime.flash.net.URLRequestMethod,air.URLStream=window.runtime.flash.net.URLStream,air.URLVariables=window.runtime.flash.net.URLVariables,air.Socket=window.runtime.flash.net.Socket,air.XMLSocket=window.runtime.flash.net.XMLSocket,air.SecureSocket=window.runtime.flash.net.SecureSocket,air.CertificateStatus=window.runtime.flash.security.CertificateStatus,air.Responder=window.runtime.flash.net.Responder,air.ObjectEncoding=window.runtime.flash.net.ObjectEncoding,air.NetStream=window.runtime.flash.net.NetStream,air.NetStreamInfo=window.runtime.flash.net.NetStreamInfo,air.NetStreamPlayOptions=window.runtime.flash.net.NetStreamPlayOptions,air.NetStreamPlayTransitions=window.runtime.flash.net.NetStreamPlayTransitions,air.SharedObject=window.runtime.flash.net.SharedObject,air.SharedObjectFlushStatus=window.runtime.flash.net.SharedObjectFlushStatus,air.DatagramSocket=window.runtime.flash.net.DatagramSocket,air.NetworkInfo=window.runtime.flash.net.NetworkInfo,air.ServerSocket=window.runtime.flash.net.ServerSocket,air.IPVersion=window.runtime.flash.net.IPVersion,air.DNSResolver=window.runtime.flash.net.dns.DNSResolver,air.ARecord=window.runtime.flash.net.dns.ARecord,air.AAAARecord=window.runtime.flash.net.dns.AAAARecord,air.MXRecord=window.runtime.flash.net.dns.MXRecord,air.PTRRecord=window.runtime.flash.net.dns.PTRRecord,air.SRVRecord=window.runtime.flash.net.dns.SRVRecord,air.Capabilities=window.runtime.flash.system.Capabilities,air.System=window.runtime.flash.system.System,air.Security=window.runtime.flash.system.Security,air.Updater=window.runtime.flash.desktop.Updater,air.Clipboard=window.runtime.flash.desktop.Clipboard,air.ClipboardFormats=window.runtime.flash.desktop.ClipboardFormats,air.ClipboardTransferMode=window.runtime.flash.desktop.ClipboardTransferMode,air.NativeDragManager=window.runtime.flash.desktop.NativeDragManager,air.NativeDragOptions=window.runtime.flash.desktop.NativeDragOptions,air.NativeDragActions=window.runtime.flash.desktop.NativeDragActions,air.Icon=window.runtime.flash.desktop.Icon,air.DockIcon=window.runtime.flash.desktop.DockIcon,air.InteractiveIcon=window.runtime.flash.desktop.InteractiveIcon,air.NotificationType=window.runtime.flash.desktop.NotificationType,air.SystemTrayIcon=window.runtime.flash.desktop.SystemTrayIcon,air.NativeApplication=window.runtime.flash.desktop.NativeApplication,air.NativeProcess=window.runtime.flash.desktop.NativeProcess,air.NativeProcessStartupInfo=window.runtime.flash.desktop.NativeProcessStartupInfo,air.NativeMenu=window.runtime.flash.display.NativeMenu,air.NativeMenuItem=window.runtime.flash.display.NativeMenuItem,air.Screen=window.runtime.flash.display.Screen,air.Loader=window.runtime.flash.display.Loader,air.Bitmap=window.runtime.flash.display.Bitmap,air.BitmapData=window.runtime.flash.display.BitmapData,air.Keyboard=window.runtime.flash.ui.Keyboard,air.KeyLocation=window.runtime.flash.ui.KeyLocation,air.Mouse=window.runtime.flash.ui.Mouse,air.ReferencesValidationSetting=window.runtime.flash.security.ReferencesValidationSetting,air.RevocationCheckSettings=window.runtime.flash.security.RevocationCheckSettings,air.SignatureStatus=window.runtime.flash.security.SignatureStatus,air.SignerTrustSettings=window.runtime.flash.security.SignerTrustSettings,air.XMLSignatureValidator=window.runtime.flash.security.XMLSignatureValidator,air.ByteArray=window.runtime.flash.utils.ByteArray,air.CompressionAlgorithm=window.runtime.flash.utils.CompressionAlgorithm,air.Endian=window.runtime.flash.utils.Endian,air.Timer=window.runtime.flash.utils.Timer,air.IDataInput=window.runtime.flash.utils.IDataInput,air.IDataOutput=window.runtime.flash.utils.IDataOutput,air.HTMLLoader=window.runtime.flash.html.HTMLLoader,air.HTMLPDFCapability=window.runtime.flash.html.HTMLPDFCapability,air.Vector=window.runtime.Vector,air.ID3Info=window.runtime.flash.media.ID3Info,air.Sound=window.runtime.flash.media.Sound,air.SoundChannel=window.runtime.flash.media.SoundChannel,air.SoundLoaderContext=window.runtime.flash.media.SoundLoaderContext,air.SoundMixer=window.runtime.flash.media.SoundMixer,air.SoundTransform=window.runtime.flash.media.SoundTransform,air.Microphone=window.runtime.flash.media.Microphone,air.Video=window.runtime.flash.media.Video,air.Camera=window.runtime.flash.media.Camera,air.SoundCodec=window.runtime.flash.media.SoundCodec,air.EncryptedLocalStore=window.runtime.flash.data.EncryptedLocalStore,air.SQLCollationType=window.runtime.flash.data.SQLCollationType,air.SQLColumnNameStyle=window.runtime.flash.data.SQLColumnNameStyle,air.SQLColumnSchema=window.runtime.flash.data.SQLColumnSchema,air.SQLConnection=window.runtime.flash.data.SQLConnection,air.SQLError=window.runtime.flash.errors.SQLError,air.SQLErrorEvent=window.runtime.flash.events.SQLErrorEvent,air.SQLErrorOperation=window.runtime.flash.errors.SQLErrorOperation,air.SQLEvent=window.runtime.flash.events.SQLEvent,air.SQLIndexSchema=window.runtime.flash.data.SQLIndexSchema,air.SQLMode=window.runtime.flash.data.SQLMode,air.SQLResult=window.runtime.flash.data.SQLResult,air.SQLSchema=window.runtime.flash.data.SQLSchema,air.SQLSchemaResult=window.runtime.flash.data.SQLSchemaResult,air.SQLStatement=window.runtime.flash.data.SQLStatement,air.SQLTableSchema=window.runtime.flash.data.SQLTableSchema,air.SQLTransactionLockType=window.runtime.flash.data.SQLTransactionLockType,air.SQLTriggerSchema=window.runtime.flash.data.SQLTriggerSchema,air.SQLUpdateEvent=window.runtime.flash.events.SQLUpdateEvent,air.SQLViewSchema=window.runtime.flash.data.SQLViewSchema,air.__defineGetter__("ServiceMonitor",function(){return window.runtime.air.net.ServiceMonitor}),air.__defineGetter__("SocketMonitor",function(){return window.runtime.air.net.SocketMonitor}),air.__defineGetter__("URLMonitor",function(){return window.runtime.air.net.URLMonitor}),air.__defineGetter__("SecureSocketMonitor",function(){return window.runtime.air.net.SecureSocketMonitor}),air.__defineGetter__("URLFilePromise",function(){return window.runtime.air.desktop.URLFilePromise}),air.__defineGetter__("ApplicationUpdater",function(){return window.runtime.air.update.ApplicationUpdater}),air.__defineGetter__("ApplicationUpdaterUI",function(){return window.runtime.air.update.ApplicationUpdaterUI}),air.__defineGetter__("UpdateEvent",function(){return window.runtime.air.update.events.UpdateEvent}),air.__defineGetter__("StatusUpdateEvent",function(){return window.runtime.air.update.events.StatusUpdateEvent}),air.__defineGetter__("StatusUpdateErrorEvent",function(){return window.runtime.air.update.events.StatusUpdateErrorEvent}),air.__defineGetter__("DownloadErrorEvent",function(){return window.runtime.air.update.events.DownloadErrorEvent}),air.__defineGetter__("StatusFileUpdateEvent",function(){return window.runtime.air.update.events.StatusFileUpdateEvent}),air.__defineGetter__("StatusFileUpdateErrorEvent",function(){return window.runtime.air.update.events.StatusFileUpdateErrorEvent})); -------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | $(function(){ 2 | var user = { 3 | os: air.Capabilities.os.indexOf('win'), 4 | watching: [], 5 | defaultBg: false, 6 | activityLen: 0, 7 | loggedIn: false, 8 | settings: { 9 | startAtLogin: true, 10 | toured: null, // If the user has seen/used the tour 11 | username: null, 12 | loginName: null, 13 | apiToken: null, 14 | basicToken: null, 15 | lastUpdate: null, 16 | lastDbUpdate: null, 17 | activity: [] 18 | } 19 | }, 20 | appInfo = { 21 | version: '0.0.7' 22 | }, 23 | appState = { 24 | noteOpen: 0, 25 | processDetection: null, 26 | }, 27 | bottom = $('#bottom'), 28 | loader = $('#loading'), 29 | activityList = $('#activity-list'), 30 | settingsOvl = $('#settings-ovl'), 31 | middle = $('#middle'), 32 | activityLastUpdate = null, 33 | ui = { 34 | note: { 35 | window: null, 36 | $body: null, 37 | open: false 38 | }, 39 | showSettings: function(){ 40 | settingsOvl.fadeIn(150); 41 | }, 42 | hideSettings: function(){ 43 | settingsOvl.fadeOut(150); 44 | }, 45 | glowRed: function(){ 46 | window.nativeWindow.notifyUser(air.NotificationType.CRITICAL); 47 | }, 48 | glowYellow: function(){ 49 | window.nativeWindow.notifyUser(air.NotificationType.INFORMATIONAL); 50 | }, 51 | centerWindow: function(){ 52 | window.nativeWindow.x = (air.Capabilities.screenResolutionX - window.nativeWindow.width) / 2; 53 | window.nativeWindow.y = (air.Capabilities.screenResolutionY - window.nativeWindow.height) / 2; 54 | }, 55 | loading: function(message){ 56 | //var dotCounter = 0; 57 | 58 | loader.addClass('visible').text(message + '...'); 59 | /* 60 | // By design principle, one loading animation is enough 61 | var dotInterval = setInterval(function(){ 62 | if(dotCounter === 3){ 63 | loader.text(message); 64 | dotCounter = 0; 65 | } else { 66 | loader.text(loader.text() + '.'); 67 | dotCounter++; 68 | } 69 | }, 500); 70 | */ 71 | }, 72 | doneLoading: function(){ 73 | loader.removeClass('visible'); 74 | }, 75 | message: function(message){ 76 | $('#top-user').text(message); 77 | }, 78 | initNote: function(){ 79 | if(!appState.noteOpen){ 80 | 81 | // Small growl-type notifications! 82 | var noteObj = { 83 | note: new air.NativeWindowInitOptions(), 84 | screenInfo: air.Screen.mainScreen.visibleBounds, 85 | noteBounds: new air.Rectangle( 86 | air.Screen.mainScreen.visibleBounds.width - 312 - 30, 87 | air.Screen.mainScreen.visibleBounds.height - 120 - 30, 88 | 312, // Width 89 | 120 // Height 90 | ) 91 | } 92 | 93 | noteObj.note.resizable = false; 94 | noteObj.note.transparent = true; 95 | noteObj.note.maximizable = false; 96 | noteObj.note.type = air.NativeWindowType.LIGHTWEIGHT; 97 | //noteObj.note.type = air.NativeWindowType.NORMAL; // FOR DEV MODE 98 | noteObj.note.systemChrome = air.NativeWindowSystemChrome.NONE; 99 | 100 | noteObj.noteLoader = air.HTMLLoader.createRootWindow(true, noteObj.note, false, noteObj.noteBounds); 101 | 102 | noteObj.noteLoader.paintsDefaultBackground = false; 103 | noteObj.noteLoader.stage.nativeWindow.alwaysInFront = true; 104 | noteObj.noteLoader.navigateInSystemBrowser = true; 105 | 106 | appState.openNotes = true; // Don't open any more 107 | noteObj.noteLoader.load(new air.URLRequest('note.html')); 108 | 109 | ui.note.window = noteObj.noteLoader.window; // Save the note window for reuse 110 | noteObj = null; 111 | } 112 | }, 113 | showNote: function(title, message, type, callback){ 114 | type = type || 'scrobble'; 115 | 116 | if(!ui.note.open){ 117 | 118 | air.trace('New note opened!'); 119 | 120 | var $note = $(ui.note.window.document.body), 121 | $msg = $note.find('#message-bg'), 122 | $close = $note.find('#message-close'); 123 | 124 | ui.note.open = true; 125 | 126 | $msg.addClass('visible ' + type); 127 | $note.find('#message-title').html(title); 128 | $note.find('#message-desc').html(message); 129 | $note.find('#message-icon').css('background-image', 'url(img/nicons/' + type + '.jpg)'); 130 | 131 | var noteTO = setTimeout(function(){ 132 | $msg.removeClass('visible ' + type); 133 | $msg.off(); 134 | $close.off(); 135 | ui.note.open = false; 136 | }, 7000); 137 | 138 | $close.click(function(e){ 139 | e.stopPropagation(); 140 | clearTimeout(noteTO); 141 | $msg.removeClass('visible ' + type); 142 | air.trace('Closed note by cross'); 143 | $msg.off(); 144 | $close.off(); 145 | ui.note.open = false; 146 | }); 147 | 148 | $msg.click(function(){ 149 | $msg.off(); 150 | $close.off(); 151 | if(!$msg.hasClass('scrobble')){ 152 | clearTimeout(noteTO); 153 | $msg.removeClass('visible ' + type); 154 | ui.note.open = false; 155 | air.trace('Closed note by scrobble'); 156 | } else { 157 | clearTimeout(noteTO); 158 | setTimeout(function(){ 159 | $msg.removeClass('visible ' + type); 160 | ui.note.open = false; 161 | }, 1000); 162 | air.trace('Closed note by click'); 163 | } 164 | if(callback){ 165 | callback(); 166 | air.trace('Run note callback'); 167 | } 168 | }).mouseup(function(e){ 169 | e.stopPropagation(); 170 | if(e.button === 2 && $msg.hasClass('scrobble')){ 171 | clearTimeout(noteTO); 172 | $msg.removeClass('visible scrobble'); 173 | $msg.off(); 174 | $close.off(); 175 | ui.note.open = false; 176 | air.trace('Closed note by right-click'); 177 | } 178 | }); 179 | } 180 | } 181 | }, 182 | helpers = { 183 | isNumber: function(number){ 184 | return !isNaN(parseFloat(number)) && isFinite(number); 185 | }, 186 | openInBrowser: function(url){ 187 | var request = new air.URLRequest(url); 188 | air.navigateToURL(request); 189 | }, 190 | activityObject: function(){ 191 | var activity = { 192 | published: new Date().getTime(), 193 | verb: null, 194 | actor: { 195 | displayName: user.settings.username, 196 | url: 'http://hummingbird.me/users/' + user.settings.loginName + '/library' 197 | }, 198 | target: {}, 199 | object: {} 200 | } 201 | return activity; 202 | }, 203 | generateColor: function(str){ 204 | // str to hash 205 | for (var i = 0, hash = 0; i < str.length; hash = str.charCodeAt(i++) + ((hash << 5) - hash)); 206 | 207 | // int/hash to hex 208 | for (var i = 0, colour = "#"; i < 3; colour += ("00" + ((hash >> i++ * 8) & 0xFF).toString(16)).slice(-2)); 209 | 210 | return colour; 211 | }, 212 | displayActivity: function(){ 213 | var activity = user.settings.activity, 214 | events = {}; 215 | 216 | if(activity.length === 0 && !user.defaultBg){ 217 | if(!middle.hasClass('new')){ 218 | middle.addClass('new'); 219 | } 220 | } else if(user.activityLen < activity.length || (new Date().getTime() - activityLastUpdate) > 10000){ 221 | 222 | if(!user.defaultBg){ 223 | middle.removeClass('new'); 224 | user.defaultBg = true; 225 | } 226 | 227 | activityLastUpdate = new Date().getTime(); 228 | 229 | user.activityLen = activity.length; 230 | activityList.empty(); 231 | 232 | for(var i = 0; i < activity.length; i++){ // Bundle into "events" 233 | if(events[activity[i].object.id]){ 234 | events[activity[i].object.id].push(activity[i]); 235 | } else { 236 | events[activity[i].object.id] = [activity[i]]; 237 | } 238 | } 239 | 240 | for(var _id in events){ // Sort each individual array, desc. 241 | events[_id].sort(function(a, b){ 242 | a = new Date(a.published); 243 | b = new Date(b.published); 244 | return a > b ? -1 : a < b ? 1 : 0; 245 | }); 246 | 247 | for(var i = 0; i < events[_id].length; i++){ 248 | var eventTemp = events[_id][i]; 249 | 250 | if(i == 0){ 251 | var activityItem = '
' + moment(eventTemp.published).fromNow() + '
' + eventTemp.actor.displayName + ' ' + eventTemp.verb + ' ' + eventTemp.object.displayName + ' to ' + eventTemp.target.displayName + '.
'; 252 | 253 | if(events[_id].length > 1){ 254 | activityItem = '
' + activityItem + '
'; 255 | } else { 256 | activityItem = '
' + activityItem + '
'; 257 | } 258 | 259 | activityList.prepend(activityItem); 260 | 261 | } else if(i < 10){ 262 | 263 | var activityItem = '
  • ' + moment(eventTemp.published).fromNow() + '
    ' + eventTemp.actor.displayName + ' ' + eventTemp.verb + ' ' + eventTemp.object.displayName + '.
  • '; 264 | 265 | $('.sub-activity-list[data-id="' + eventTemp.object.id + '"]').append(activityItem); 266 | } 267 | } 268 | } 269 | 270 | $('.activity-wrap').tsort({ attr: 'data-lastupdate', order: 'desc' }); 271 | 272 | /* 273 | for(var i = 0; i < activity.length; i++){ 274 | if(activity[i].verb == 'connected'){ 275 | var activityItem = '
  • ' + moment(activity[i].published).fromNow() + '
    ' + activity[i].actor.displayName + ' ' + activity[i].verb + ' ' + activity[i].object.displayName + ' to ' + activity[i].target.displayName + '.
  • '; 276 | activityList.prepend(activityItem); 277 | } else { 278 | //var activityItem = '
  • ' + moment(activity[i].published).fromNow() + '
    ' + activity[i].actor.displayName + ' ' + activity[i].verb + ' ' + activity[i].object.displayName + ' to ' + activity[i].target.displayName + '.
  • '; 279 | var activityItem = '
  • ' + moment(activity[i].published).fromNow() + '
    ' + activity[i].actor.displayName + ' ' + activity[i].verb + ' ' + activity[i].object.displayName + ' to ' + activity[i].target.displayName + '.
  • '; 280 | activityList.prepend(activityItem); 281 | } 282 | } 283 | */ 284 | } 285 | }, 286 | // Left new, right old 287 | versionCompare: function(left, right){ 288 | if (typeof left + typeof right != 'stringstring') 289 | return false; 290 | 291 | var a = left.split('.') 292 | , b = right.split('.') 293 | , i = 0, len = Math.max(a.length, b.length); 294 | 295 | for (; i < len; i++) { 296 | if ((a[i] && !b[i] && parseInt(a[i]) > 0) || (parseInt(a[i]) > parseInt(b[i]))) { 297 | return 1; 298 | } else if ((b[i] && !a[i] && parseInt(b[i]) > 0) || (parseInt(a[i]) < parseInt(b[i]))) { 299 | return -1; 300 | } 301 | } 302 | return 0; 303 | }, 304 | checkUpdates: function(){ 305 | ui.loading('Checking for updates'); 306 | setTimeout(function(){ 307 | $.ajax({ 308 | type: 'get', 309 | url: 'https://cdn.rawgit.com/Desuvader/Hummingbird-Updater/master/version', 310 | success: function(res){ 311 | air.trace('Retrieved version info'); 312 | if(helpers.versionCompare(res.version, appInfo.version) === 1){ 313 | 314 | ui.loading('Downloading new update'); 315 | 316 | var updateLoader = new air.URLLoader(), 317 | updateStream = new air.FileStream(), 318 | //updateByteArray = new ByteArray(), 319 | updateNP = new air.NativeProcess(), 320 | updateNPSI = new air.NativeProcessStartupInfo(); 321 | 322 | updateLoader.dataFormat = air.URLLoaderDataFormat.BINARY; 323 | updateLoader.load(new air.URLRequest(res.url)); 324 | updateLoader.addEventListener(air.Event.COMPLETE, function(res){ 325 | // Windows run update 326 | var updateFile = air.File.applicationStorageDirectory.resolvePath(updateFileName); 327 | air.trace(updateFile); 328 | updateStream.open(updateFile, air.FileMode.WRITE); 329 | updateStream.writeBytes(res.target.data); // Save updater 330 | updateStream.close(); 331 | updateLoader.close(); 332 | 333 | updateNPSI.executable = updateFile; 334 | updateNP.start(updateNPSI); // Run update 335 | air.NativeApplication.nativeApplication.exit(); 336 | }); 337 | } else { 338 | ui.doneLoading(); 339 | } 340 | }, 341 | error: function(){ 342 | ui.doneLoading(); 343 | } 344 | }); 345 | }, 1500); 346 | } 347 | }, 348 | app = { 349 | init: function(){ 350 | ui.initNote(); 351 | if(air.NativeApplication.supportsStartAtLogin && user.settings.startAtLogin){ 352 | //air.NativeApplication.nativeApplication.startAtLogin = true; 353 | } 354 | ui.centerWindow(); 355 | app.getUserSettings(function(){ 356 | //app.updateDatabase(); Not needed atm 357 | app.authenticate(function(){ 358 | user.loggedIn = true; 359 | $('#login-form-wrap').remove(); 360 | $('#open-herro').attr('href', 'http://hummingbird.me/users/' + user.settings.username + '/library'); 361 | helpers.checkUpdates(); 362 | ui.message('Hey, ' + user.settings.username + '!'); 363 | app.initTour(); 364 | app.detectionInit(); 365 | helpers.displayActivity(); 366 | app.createTrayIcon(); 367 | }); 368 | }); 369 | }, 370 | authenticate: function(callback){ 371 | if(user.settings.username && user.settings.apiToken){ 372 | // Continue 373 | callback(); 374 | } else { 375 | air.trace('Requires authentication!'); 376 | $('#login-form-wrap').show(); 377 | $('#login-form-submit').on('click', function(){ 378 | var $this = $(this); 379 | if($this.hasClass('disabled')){ return; } 380 | 381 | $(this).addClass('disabled'); 382 | var inputUsername = $('#login-value-username').val(), 383 | inputPassword = $('#login-value-password').val(), 384 | tempToken = null; 385 | 386 | ui.loading('Authenticating'); 387 | 388 | $.ajax({ 389 | data: { 390 | username: inputUsername, 391 | password: inputPassword 392 | }, 393 | type: 'post', 394 | url: 'http://hummingbird.me/api/v1/users/authenticate', 395 | success: function(res){ 396 | air.trace('Authenticated'); 397 | 398 | air.trace(res); 399 | 400 | user.settings.username = inputUsername.substr(0, 1).toUpperCase() + inputUsername.substr(1); // Show respect for people with these kind of uSerNAmES 401 | user.settings.password = inputPassword; 402 | user.settings.apiToken = res; 403 | app.saveUserSettings(); 404 | 405 | setTimeout(function(){ 406 | $this.removeClass('disabled'); 407 | $('#login-form-submit').off(); 408 | ui.doneLoading(); 409 | callback(); 410 | }, 1000); 411 | }, 412 | error: function(res){ 413 | air.trace('Error auth: ' + JSON.stringify(res)); 414 | setTimeout(function(){ 415 | $this.removeClass('disabled'); 416 | ui.doneLoading(); 417 | confirm('Wrong Username/API Token, try again'); 418 | }, 1000); 419 | } 420 | }); 421 | }); 422 | } 423 | }, 424 | detectionInit: function(){ // Loops forever and returns an array of videos being played 425 | 426 | // Setup a new native process and keep them separated 427 | var nativeProcessStartupInfo = new air.NativeProcessStartupInfo(), 428 | file = air.File.applicationDirectory.resolvePath('detect.cmd'), 429 | process = null; 430 | 431 | nativeProcessStartupInfo.executable = file; 432 | process = new air.NativeProcess(); 433 | process.start(nativeProcessStartupInfo); 434 | 435 | process.addEventListener(air.ProgressEvent.STANDARD_OUTPUT_DATA, function(){ 436 | var response = process.standardOutput.readUTFBytes(process.standardOutput.bytesAvailable).replace(/\s+$/, ''), // Replace any appended spaces/new lines 437 | detectedAnime = []; 438 | 439 | detectedAnime = response.split('\r\n'); 440 | 441 | for(var i = 0; i < detectedAnime.length; i++){ 442 | var tempDetected = detectedAnime[i].replace(/^.*: /, '').replace(/ - ([^-]+) VLC.*/, '').replace(/ - VLC.*/, '').replace(/\r\n/, '').replace(/^\s+/, ''), 443 | tempArr = []; 444 | 445 | if(user.watching.indexOf(tempDetected) === -1 && tempDetected.match(/(.mkv$|.avi$|.mp4$)/)){ 446 | air.trace('New episode detected!'); 447 | tempArr.push(tempDetected); // New anime was opened. Add it to the array 448 | app.scrobble(tempDetected); // Send a request to herro and then ask if the user wants to update their list 449 | } else if(user.watching.indexOf(tempDetected) > -1){ 450 | tempArr.push(tempDetected); 451 | } 452 | } 453 | 454 | user.watching = tempArr; 455 | 456 | }); 457 | 458 | appState.processDetection = process; 459 | }, 460 | scrobble: function(filename){ 461 | var anime = { 462 | // Temporary anime obj, describing the file that is being processed 463 | _id: null, 464 | slug: null, 465 | title: null, 466 | image: null, 467 | progress: null, 468 | score: null, // How well it matches the filename. Internal use only! 469 | filename: filename, 470 | }, 471 | detectedEpisodes = null; 472 | 473 | var animeTitle = anime.filename.replace(/\[.*?\]|(.mkv|.avi|.mp4)|\(.*\)/gi, '').replace(/_/g, ' ').replace(/^\s+|\s+$/g,''); 474 | var detectedEpisodes = anime.filename.replace(/_/g, ' ').match(/[\._ \-]([0-9]{2,3})[v\._ \-\[\(].*[\[\(][0-9A-Za-z]{4,8}[\)\]][\/\._ \-\[\(]/); 475 | 476 | $.ajax({ 477 | url: 'http://hummingbird.me/api/v1/search/anime?query=' + animeTitle, 478 | success: function(response){ 479 | var animeDistanceScores = []; 480 | var animeList = response; 481 | 482 | // Out stuff 483 | 484 | air.trace('animeTitle: "' + animeTitle + '"'); 485 | air.trace('detectedEpisodes: ' + detectedEpisodes); 486 | 487 | if(detectedEpisodes){ 488 | 489 | for(var i = 0; i < detectedEpisodes.length; i++){ 490 | if(helpers.isNumber(detectedEpisodes[i])){ 491 | // If it seems to be a valid number. Make it the "detected" episode. 492 | anime.progress = parseInt(parseFloat(detectedEpisodes[i])); 493 | air.trace('Decided on episode ' + anime.progress); 494 | } 495 | } 496 | 497 | for(var i = 0, l = animeList.length; i < l; i++){ 498 | 499 | if(animeList[i].title){ 500 | var distanceScore = animeTitle.distance(animeList[i].title); 501 | if(distanceScore > 0.7){ 502 | animeDistanceScores.push({ 503 | anime: animeList[i], 504 | score: distanceScore, 505 | title: animeList[i].title 506 | }); 507 | } 508 | } 509 | } 510 | 511 | distanceResults = animeDistanceScores.sort(function SortByName(a, b){ 512 | var aScore = a.score; 513 | var bScore = b.score; 514 | return ((aScore > bScore) ? -1 : ((aScore < bScore) ? 1 : 0)); 515 | }).slice(0, 3); 516 | 517 | if(distanceResults.length){ 518 | anime._id = distanceResults[0].anime.id; 519 | anime.title = distanceResults[0].title; 520 | anime.slug = distanceResults[0].anime.id; 521 | anime.image = distanceResults[0].anime.cover_image; 522 | anime.score = distanceResults[0].score; 523 | 524 | // Best results 525 | 526 | if(anime.progress){ // If we ended up with something 527 | var animeObj = anime, 528 | activity = helpers.activityObject(); 529 | ui.showNote( 530 | 'Do you want to update?', 531 | 'Detected ' + animeObj.title + ' Episode ' + animeObj.progress + '', 532 | 'scrobble', 533 | function(){ 534 | air.trace(JSON.stringify(animeObj)); 535 | activity.verb = 'scrobbled'; 536 | activity.object.id = animeObj._id; 537 | activity.object.title = animeObj.title; 538 | activity.object.progress = animeObj.progress; 539 | activity.object.displayName = animeObj.title + ' Episode ' + animeObj.progress; 540 | activity.object.url = 'http://hummingbird.me/anime/' + animeObj.slug; 541 | activity.object.image = animeObj.image; 542 | activity.target.displayName = 'their list'; 543 | user.settings.activity.push(activity); 544 | app.saveUserSettings(); 545 | 546 | // If the user confirmed the scrobble 547 | air.trace('Scrobbling...'); 548 | app.scrobbleAnime(animeObj); 549 | animeObj = null; 550 | }); 551 | //app.screenshot(anime.filename); 552 | } 553 | } else { 554 | air.trace('Nothing matched distance search'); 555 | } 556 | } 557 | 558 | // Nullify. Not sure if this thing really works 559 | animeDistanceScores = null; 560 | detectedEpisodes = null; 561 | anime = null; 562 | response = null; 563 | animeList = null; 564 | } 565 | }); 566 | }, 567 | scrobbleAnime: function(anime){ 568 | $.ajax({ 569 | type: 'post', 570 | url: 'http://hummingbird.me/api/v1/libraries/' + anime._id, 571 | data: { 572 | id: anime._id, 573 | auth_token: user.settings.apiToken, 574 | episodes_watched: anime.progress 575 | }, 576 | success: function(res){ 577 | air.trace('Updated!'); 578 | }, 579 | error: function(){ 580 | confirm('Something went wrong when updating your list. Try updating directly through Hummingbird instead!'); 581 | } 582 | }); 583 | }, 584 | initTour: function(){ 585 | if(!user.settings.toured){ 586 | 587 | var $tourWrap = $('#tour-wrap'), 588 | $tourSlideWrap = $('#tour-slide-wrap'), 589 | $tourControlWrap = $('.tour-control-wrap'), 590 | currSlide = 0; 591 | 592 | $tourWrap.show(); 593 | app.saveUserSettings(); 594 | $('#tour-text-skip').click(function(){ 595 | user.settings.toured = true; 596 | $tourWrap.addClass('hidden'); 597 | setTimeout(function(){ 598 | $tourWrap.hide(); 599 | bottom.addClass('toured'); 600 | }, 550); 601 | }); 602 | 603 | $('#tour-take').click(function(){ 604 | currSlide = 1; 605 | $tourSlideWrap.css('left', '-=360px'); 606 | $tourControlWrap.fadeIn(500); 607 | ui.showNote( 608 | 'Do you want to update?', 609 | 'This is just an example. Keep reading the tour!' 610 | ); 611 | }); 612 | 613 | $('.tour-control-left').click(function(){ 614 | if($tourSlideWrap.position().left < 0){ 615 | currSlide--; 616 | $tourSlideWrap.css('left', '-' + (currSlide * 360) + 'px'); 617 | } 618 | }); 619 | 620 | $('.tour-control-right').click(function(){ 621 | if(currSlide < 3){ 622 | currSlide++; 623 | $tourSlideWrap.css('left', '-' + (currSlide * 360) + 'px'); 624 | } else if(currSlide === 3){ 625 | currSlide++; 626 | user.settings.toured = true; 627 | app.saveUserSettings(); 628 | $tourSlideWrap.css('left', '-' + (currSlide * 360) + 'px'); 629 | $tourControlWrap.fadeOut(500); 630 | setTimeout(function(){ 631 | $tourWrap.hide(); 632 | bottom.addClass('toured'); 633 | }, 550); 634 | } 635 | }); 636 | } else { 637 | bottom.addClass('toured'); 638 | 639 | } 640 | }, 641 | replayTour: function(){ 642 | if(user.settings.toured){ 643 | user.settings.toured = false; 644 | bottom.removeClass('toured'); 645 | $('#tour-wrap').removeClass('hidden'); 646 | $('#tour-slide-wrap').css('left', '0'); 647 | app.initTour(); 648 | } 649 | }, 650 | getUserSettings: function(callback){ 651 | var settingsJSON = air.File(air.File.applicationStorageDirectory.resolvePath('settings.json')), 652 | loadedJSON = function(){ 653 | user.settings = $.parseJSON(settingsJSON.data.readUTFBytes(settingsJSON.data.bytesAvailable).toString()); 654 | settingsJSON.removeEventListener(air.Event.COMPLETE, loadedJSON); 655 | air.trace('Retrieved settings.json'); 656 | if(callback){ 657 | callback(); 658 | } 659 | } 660 | 661 | settingsJSON.addEventListener(air.Event.COMPLETE, loadedJSON); 662 | 663 | if(!settingsJSON.exists){ 664 | // If settings.json is missing, create a new one with default values. 665 | app.saveUserSettings(function(){ 666 | settingsJSON.load(); 667 | }); 668 | } else { 669 | settingsJSON.load(); 670 | } 671 | }, 672 | saveUserSettings: function(callback){ 673 | var settingsJSON = new air.FileStream(); 674 | settingsJSON.open(air.File.applicationStorageDirectory.resolvePath('settings.json'), air.FileMode.WRITE); 675 | settingsJSON.writeUTFBytes(JSON.stringify(user.settings)); 676 | settingsJSON.close(); 677 | air.trace('Settings.json has been updated'); 678 | if(callback){ 679 | callback(); 680 | } 681 | }, 682 | createTrayIcon: function(){ 683 | var iconLoadComplete = function(event){ 684 | air.NativeApplication.nativeApplication.icon.bitmaps = [event.target.content.bitmapData]; 685 | } 686 | 687 | var iconLoad = new air.Loader(); 688 | var iconMenu = new air.NativeMenu(); 689 | var iconMenuOpen = iconMenu.addItem(new air.NativeMenuItem('Open Updater')); 690 | var iconMenuClose = iconMenu.addItem(new air.NativeMenuItem('Exit')); 691 | 692 | iconMenuOpen.addEventListener(air.Event.SELECT, function(){ 693 | ui.glowYellow(); 694 | window.nativeWindow.activate(); 695 | }); 696 | 697 | iconMenuClose.addEventListener(air.Event.SELECT, function(){ 698 | if(confirm('Are you sure you want to exit?')){ 699 | air.NativeApplication.nativeApplication.icon.bitmaps = []; 700 | if(appState.processDetection){ 701 | appState.processDetection.exit(true); // Forcequit 702 | } 703 | app.saveUserSettings(function(){ 704 | air.NativeApplication.nativeApplication.exit(); 705 | }); 706 | } 707 | }); 708 | 709 | if(air.NativeApplication.supportsSystemTrayIcon){ 710 | iconLoad.contentLoaderInfo.addEventListener(air.Event.COMPLETE, iconLoadComplete); 711 | iconLoad.load(new air.URLRequest('img/16x16.png')); 712 | air.NativeApplication.nativeApplication.icon.tooltip = 'Hummingbird Updater'; 713 | air.NativeApplication.nativeApplication.icon.menu = iconMenu; 714 | 715 | air.NativeApplication.nativeApplication.icon.addEventListener(air.MouseEvent.CLICK, function(){ 716 | ui.glowYellow(); 717 | window.nativeWindow.activate(); 718 | window.nativeWindow.alwaysInFront = true; 719 | window.nativeWindow.alwaysInFront = false; 720 | }); 721 | } 722 | } 723 | } 724 | 725 | app.init(); 726 | 727 | window.nativeWindow.addEventListener(air.Event.CLOSING, function(e){ 728 | e.preventDefault(); 729 | 730 | // Remove all processes 731 | 732 | if(appState.processDetection){ 733 | appState.processDetection.exit(true); // Forcequit 734 | } 735 | 736 | // Save before closing 737 | // Weird mac bug? 738 | if(user.os !== 'mac'){ 739 | app.saveUserSettings(function(){ // If user has removed information, it will only exit. 740 | air.NativeApplication.nativeApplication.exit(); 741 | }); 742 | } else { 743 | // At change theme/set folder we save settings if mac, so we can close without saving. 744 | air.NativeApplication.nativeApplication.exit(); 745 | } 746 | }); 747 | 748 | // Yeah. I think I went a little bit too far... 749 | // The plugin has been modded, adding a few new things 750 | /* 751 | $.parallaxify({ 752 | positionProperty: 'transform', 753 | relativeEl: $('#app-wrap') 754 | }); 755 | */ 756 | 757 | setInterval(function(){ 758 | if(user.loggedIn){ 759 | //air.trace(air.System.privateMemory / 1048576); 760 | helpers.displayActivity(); 761 | //air.trace('Currently watching: ' + JSON.stringify(user.watching)); 762 | } 763 | }, 2000); 764 | 765 | $('#settings-clearrecent').click(function(){ 766 | if(confirm('Are you sure you want to clear your recent activity?')){ 767 | ui.hideSettings(); 768 | user.settings.activity = []; 769 | activityList.empty(); 770 | user.defaultBg = false; 771 | helpers.displayActivity(); 772 | app.saveUserSettings(); 773 | } 774 | }); 775 | 776 | $('#settings-retaketour').click(function(){ 777 | ui.hideSettings(); 778 | app.replayTour(); 779 | }); 780 | 781 | $('#settings-clearall').click(function(){ 782 | if(confirm('Are you sure you want to clear everything?')){ 783 | air.trace('Resetting..'); 784 | air.File.applicationStorageDirectory.resolvePath('settings.json').deleteFile(); 785 | if(appState.processDetection){ 786 | appState.processDetection.exit(true); // Forcequit 787 | } 788 | location.reload(); 789 | //air.NativeApplication.nativeApplication.exit(); 790 | } 791 | }); 792 | 793 | $('#settings-close').click(function(){ 794 | ui.hideSettings(); 795 | }); 796 | 797 | $('#open-settings').click(function(){ 798 | ui.showSettings(); 799 | }); 800 | 801 | $('#top').mousedown(function(){ 802 | window.nativeWindow.startMove(); 803 | }); 804 | 805 | $('#top-close').click(function(){ 806 | if(user.loggedIn){ 807 | window.nativeWindow.visible = false; 808 | ui.showNote( 809 | 'Running in the background', 810 | 'You can still access the updater through the system tray', 811 | 'update' 812 | ); 813 | } else { 814 | if(appState.processDetection){ 815 | appState.processDetection.exit(true); // Forcequit 816 | } 817 | app.saveUserSettings(function(){ 818 | air.NativeApplication.nativeApplication.exit(); 819 | }); 820 | } 821 | /* 822 | if(confirm('Are you sure you want to exit?')){ 823 | if(appState.processDetection){ 824 | appState.processDetection.exit(true); // Forcequit 825 | } 826 | app.saveUserSettings(function(){ 827 | air.NativeApplication.nativeApplication.exit(); 828 | }); 829 | } 830 | */ 831 | }); 832 | 833 | $('#top-minimize').click(function(){ 834 | window.nativeWindow.minimize(); 835 | air.System.gc(); 836 | }); 837 | 838 | $('body').on('click', 'a[target="_blank"]', function(event){ 839 | event.preventDefault(); 840 | helpers.openInBrowser(this.href); 841 | }); 842 | }); -------------------------------------------------------------------------------- /js/app.min.js: -------------------------------------------------------------------------------- 1 | $(function(){var e={os:air.Capabilities.os.indexOf("win"),watching:[],defaultBg:!1,activityLen:0,loggedIn:!1,settings:{startAtLogin:!0,toured:null,username:null,loginName:null,apiToken:null,basicToken:null,lastUpdate:null,lastDbUpdate:null,activity:[]}},t={version:"0.0.7"},i={noteOpen:0,processDetection:null},n=$("#bottom"),a=$("#loading"),o=$("#activity-list"),s=$("#settings-ovl"),r=$("#middle"),c=null,l={note:{window:null,$body:null,open:!1},showSettings:function(){s.fadeIn(150)},hideSettings:function(){s.fadeOut(150)},glowRed:function(){window.nativeWindow.notifyUser(air.NotificationType.CRITICAL)},glowYellow:function(){window.nativeWindow.notifyUser(air.NotificationType.INFORMATIONAL)},centerWindow:function(){window.nativeWindow.x=(air.Capabilities.screenResolutionX-window.nativeWindow.width)/2,window.nativeWindow.y=(air.Capabilities.screenResolutionY-window.nativeWindow.height)/2},loading:function(e){a.addClass("visible").text(e+"...")},doneLoading:function(){a.removeClass("visible")},message:function(e){$("#top-user").text(e)},initNote:function(){if(!i.noteOpen){var e={note:new air.NativeWindowInitOptions,screenInfo:air.Screen.mainScreen.visibleBounds,noteBounds:new air.Rectangle(air.Screen.mainScreen.visibleBounds.width-312-30,air.Screen.mainScreen.visibleBounds.height-120-30,312,120)};e.note.resizable=!1,e.note.transparent=!0,e.note.maximizable=!1,e.note.type=air.NativeWindowType.LIGHTWEIGHT,e.note.systemChrome=air.NativeWindowSystemChrome.NONE,e.noteLoader=air.HTMLLoader.createRootWindow(!0,e.note,!1,e.noteBounds),e.noteLoader.paintsDefaultBackground=!1,e.noteLoader.stage.nativeWindow.alwaysInFront=!0,e.noteLoader.navigateInSystemBrowser=!0,i.openNotes=!0,e.noteLoader.load(new air.URLRequest("note.html")),l.note.window=e.noteLoader.window,e=null}},showNote:function(e,t,i,n){if(i=i||"scrobble",!l.note.open){air.trace("New note opened!");var a=$(l.note.window.document.body),o=a.find("#message-bg"),s=a.find("#message-close");l.note.open=!0,o.addClass("visible "+i),a.find("#message-title").html(e),a.find("#message-desc").html(t),a.find("#message-icon").css("background-image","url(img/nicons/"+i+".jpg)");var r=setTimeout(function(){o.removeClass("visible "+i),o.off(),s.off(),l.note.open=!1},7e3);s.click(function(e){e.stopPropagation(),clearTimeout(r),o.removeClass("visible "+i),air.trace("Closed note by cross"),o.off(),s.off(),l.note.open=!1}),o.click(function(){o.off(),s.off(),o.hasClass("scrobble")?(clearTimeout(r),setTimeout(function(){o.removeClass("visible "+i),l.note.open=!1},1e3),air.trace("Closed note by click")):(clearTimeout(r),o.removeClass("visible "+i),l.note.open=!1,air.trace("Closed note by scrobble")),n&&(n(),air.trace("Run note callback"))}).mouseup(function(e){e.stopPropagation(),2===e.button&&o.hasClass("scrobble")&&(clearTimeout(r),o.removeClass("visible scrobble"),o.off(),s.off(),l.note.open=!1,air.trace("Closed note by right-click"))})}}},d={isNumber:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},openInBrowser:function(e){var t=new air.URLRequest(e);air.navigateToURL(t)},activityObject:function(){var t={published:(new Date).getTime(),verb:null,actor:{displayName:e.settings.username,url:"http://hummingbird.me/users/"+e.settings.loginName+"/library"},target:{},object:{}};return t},generateColor:function(e){for(var t=0,i=0;tt;n+=("00"+(i>>8*t++&255).toString(16)).slice(-2));return n},displayActivity:function(){var t=e.settings.activity,i={};if(0!==t.length||e.defaultBg){if(e.activityLen1e4){e.defaultBg||(r.removeClass("new"),e.defaultBg=!0),c=(new Date).getTime(),e.activityLen=t.length,o.empty();for(var n=0;nt?-1:t>e?1:0});for(var n=0;n
    '+moment(s.published).fromNow()+'
    '+s.actor.displayName+" "+s.verb+' '+s.object.displayName+" to "+s.target.displayName+".
    ";l=i[a].length>1?'
    '+l+'
      ':'
      '+l+"
      ",o.prepend(l)}else if(10>n){var l='
    • '+moment(s.published).fromNow()+'
      '+s.actor.displayName+" "+s.verb+' '+s.object.displayName+".
    • ";$('.sub-activity-list[data-id="'+s.object.id+'"]').append(l)}}}$(".activity-wrap").tsort({attr:"data-lastupdate",order:"desc"})}}else r.hasClass("new")||r.addClass("new")},versionCompare:function(e,t){if(typeof e+typeof t!="stringstring")return!1;for(var i=e.split("."),n=t.split("."),a=0,o=Math.max(i.length,n.length);o>a;a++){if(i[a]&&!n[a]&&parseInt(i[a])>0||parseInt(i[a])>parseInt(n[a]))return 1;if(n[a]&&!i[a]&&parseInt(n[a])>0||parseInt(i[a])-1&&s.push(o)}e.watching=s}),i.processDetection=a},scrobble:function(t){var i={_id:null,slug:null,title:null,image:null,progress:null,score:null,filename:t},n=null,a=i.filename.replace(/\[.*?\]|(.mkv|.avi|.mp4)|\(.*\)/gi,"").replace(/_/g," ").replace(/^\s+|\s+$/g,""),n=i.filename.replace(/_/g," ").match(/[\._ \-]([0-9]{2,3})[v\._ \-\[\(].*[\[\(][0-9A-Za-z]{4,8}[\)\]][\/\._ \-\[\(]/);$.ajax({url:"http://hummingbird.me/api/v1/search/anime?query="+a,success:function(t){var o=[],s=t;if(air.trace('animeTitle: "'+a+'"'),air.trace("detectedEpisodes: "+n),n){for(var r=0;rr;r++)if(s[r].title){var p=a.distance(s[r].title);p>.7&&o.push({anime:s[r],score:p,title:s[r].title})}if(distanceResults=o.sort(function(e,t){var i=e.score,n=t.score;return i>n?-1:n>i?1:0}).slice(0,3),distanceResults.length){if(i._id=distanceResults[0].anime.id,i.title=distanceResults[0].title,i.slug=distanceResults[0].anime.id,i.image=distanceResults[0].anime.cover_image,i.score=distanceResults[0].score,i.progress){var v=i,g=d.activityObject();l.showNote("Do you want to update?",'Detected '+v.title+" Episode "+v.progress+"","scrobble",function(){air.trace(JSON.stringify(v)),g.verb="scrobbled",g.object.id=v._id,g.object.title=v.title,g.object.progress=v.progress,g.object.displayName=v.title+" Episode "+v.progress,g.object.url="http://hummingbird.me/anime/"+v.slug,g.object.image=v.image,g.target.displayName="their list",e.settings.activity.push(g),u.saveUserSettings(),air.trace("Scrobbling..."),u.scrobbleAnime(v),v=null})}}else air.trace("Nothing matched distance search")}o=null,n=null,i=null,t=null,s=null}})},scrobbleAnime:function(t){$.ajax({type:"post",url:"http://hummingbird.me/api/v1/libraries/"+t._id,data:{id:t._id,auth_token:e.settings.apiToken,episodes_watched:t.progress},success:function(){air.trace("Updated!")},error:function(){confirm("Something went wrong when updating your list. Try updating directly through Hummingbird instead!")}})},initTour:function(){if(e.settings.toured)n.addClass("toured");else{var t=$("#tour-wrap"),i=$("#tour-slide-wrap"),a=$(".tour-control-wrap"),o=0;t.show(),u.saveUserSettings(),$("#tour-text-skip").click(function(){e.settings.toured=!0,t.addClass("hidden"),setTimeout(function(){t.hide(),n.addClass("toured")},550)}),$("#tour-take").click(function(){o=1,i.css("left","-=360px"),a.fadeIn(500),l.showNote("Do you want to update?","This is just an example. Keep reading the tour!")}),$(".tour-control-left").click(function(){i.position().left<0&&(o--,i.css("left","-"+360*o+"px"))}),$(".tour-control-right").click(function(){3>o?(o++,i.css("left","-"+360*o+"px")):3===o&&(o++,e.settings.toured=!0,u.saveUserSettings(),i.css("left","-"+360*o+"px"),a.fadeOut(500),setTimeout(function(){t.hide(),n.addClass("toured")},550))})}},replayTour:function(){e.settings.toured&&(e.settings.toured=!1,n.removeClass("toured"),$("#tour-wrap").removeClass("hidden"),$("#tour-slide-wrap").css("left","0"),u.initTour())},getUserSettings:function(t){var i=air.File(air.File.applicationStorageDirectory.resolvePath("settings.json")),n=function(){e.settings=$.parseJSON(i.data.readUTFBytes(i.data.bytesAvailable).toString()),i.removeEventListener(air.Event.COMPLETE,n),air.trace("Retrieved settings.json"),t&&t()};i.addEventListener(air.Event.COMPLETE,n),i.exists?i.load():u.saveUserSettings(function(){i.load()})},saveUserSettings:function(t){var i=new air.FileStream;i.open(air.File.applicationStorageDirectory.resolvePath("settings.json"),air.FileMode.WRITE),i.writeUTFBytes(JSON.stringify(e.settings)),i.close(),air.trace("Settings.json has been updated"),t&&t()},createTrayIcon:function(){var e=function(e){air.NativeApplication.nativeApplication.icon.bitmaps=[e.target.content.bitmapData]},t=new air.Loader,n=new air.NativeMenu,a=n.addItem(new air.NativeMenuItem("Open Updater")),o=n.addItem(new air.NativeMenuItem("Exit"));a.addEventListener(air.Event.SELECT,function(){l.glowYellow(),window.nativeWindow.activate()}),o.addEventListener(air.Event.SELECT,function(){confirm("Are you sure you want to exit?")&&(air.NativeApplication.nativeApplication.icon.bitmaps=[],i.processDetection&&i.processDetection.exit(!0),u.saveUserSettings(function(){air.NativeApplication.nativeApplication.exit()}))}),air.NativeApplication.supportsSystemTrayIcon&&(t.contentLoaderInfo.addEventListener(air.Event.COMPLETE,e),t.load(new air.URLRequest("img/16x16.png")),air.NativeApplication.nativeApplication.icon.tooltip="Hummingbird Updater",air.NativeApplication.nativeApplication.icon.menu=n,air.NativeApplication.nativeApplication.icon.addEventListener(air.MouseEvent.CLICK,function(){l.glowYellow(),window.nativeWindow.activate(),window.nativeWindow.alwaysInFront=!0,window.nativeWindow.alwaysInFront=!1}))}};u.init(),window.nativeWindow.addEventListener(air.Event.CLOSING,function(t){t.preventDefault(),i.processDetection&&i.processDetection.exit(!0),"mac"!==e.os?u.saveUserSettings(function(){air.NativeApplication.nativeApplication.exit()}):air.NativeApplication.nativeApplication.exit()}),setInterval(function(){e.loggedIn&&d.displayActivity()},2e3),$("#settings-clearrecent").click(function(){confirm("Are you sure you want to clear your recent activity?")&&(l.hideSettings(),e.settings.activity=[],o.empty(),e.defaultBg=!1,d.displayActivity(),u.saveUserSettings())}),$("#settings-retaketour").click(function(){l.hideSettings(),u.replayTour()}),$("#settings-clearall").click(function(){confirm("Are you sure you want to clear everything?")&&(air.trace("Resetting.."),air.File.applicationStorageDirectory.resolvePath("settings.json").deleteFile(),i.processDetection&&i.processDetection.exit(!0),location.reload())}),$("#settings-close").click(function(){l.hideSettings()}),$("#open-settings").click(function(){l.showSettings()}),$("#top").mousedown(function(){window.nativeWindow.startMove()}),$("#top-close").click(function(){e.loggedIn?(window.nativeWindow.visible=!1,l.showNote("Running in the background","You can still access the updater through the system tray","update")):(i.processDetection&&i.processDetection.exit(!0),u.saveUserSettings(function(){air.NativeApplication.nativeApplication.exit()}))}),$("#top-minimize").click(function(){window.nativeWindow.minimize(),air.System.gc()}),$("body").on("click",'a[target="_blank"]',function(e){e.preventDefault(),d.openInBrowser(this.href)})}); -------------------------------------------------------------------------------- /js/parallax_mod.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Parallaxify.js v0.0.2 3 | * http://hwthorn.github.io/parallaxify 4 | * 5 | * Copyright 2013, Felix Pflaum 6 | * Released under the MIT license 7 | * http://hwthorn.mit-license.org 8 | * 9 | * Based on stellar.js by Mark Dalgleish 10 | * http://markdalgleish.com/projects/stellar.js 11 | */ 12 | 13 | ;(function($, window, document, undefined) { 14 | 15 | var pluginName = 'parallaxify', 16 | maxFPS = 30, 17 | defaults = { 18 | positionProperty: 'position', 19 | horizontalParallax: true, 20 | verticalParallax: true, 21 | parallaxBackgrounds: true, 22 | parallaxElements: true, 23 | responsive: false, 24 | useMouseMove: true, 25 | useGyroscope: true, 26 | alphaFilter: 0.9, // use Low Pass Filter to smooth sensor readings (1 = no filter) 27 | motionType: 'natural', 28 | mouseMotionType: 'gaussian', 29 | inputPriority: 'mouse', // define which input device has priority over the other 'mouse' or 'gyroscope' 30 | motionAngleX: 80, // (0 < motionAngle < 90) delta angle that is used to render max parallax in this direction 31 | motionAngleY: 80, 32 | adjustBasePosition: true, // using Low Pass Filter to adjust base position 33 | alphaPosition: 0.05, // alpha for Low Pass Filter used to adjust average position 34 | relativeEl: null, // Parallax frame 35 | inverted: false 36 | }, 37 | 38 | // Options for positioning of elements 39 | // e.g. using css positioning with top and left 40 | // or using css transforms 41 | positionProperty = { 42 | position: { 43 | setLeft: function($element, left) { $element.css('left', left); }, 44 | setTop: function($element, top) { $element.css('top', top); } 45 | }, 46 | transform: { 47 | setPosition: function($element, left, originalLeft, top, originalTop) { 48 | $element[0].style[prefixedTransform] = 'translate3d(' + (left - originalLeft) + 'px, ' + (top - originalTop) + 'px, 0)'; 49 | } 50 | } 51 | }, 52 | 53 | // approximation of Gaussian cumulative distribution function with parameter a to influence standard deviation sigma 54 | gCDFApprox = function(x, a) { 55 | return 1 / (1 + Math.exp(-(0.07056*a*(x^3))-(1.5976*a*x))); 56 | }, 57 | 58 | // low pass filter for motion events (http://en.wikipedia.org/wiki/Low-pass_filter) 59 | lowPassFilter = function(curSignal, prevSignal, alpha) { 60 | if (prevSignal === null) return curSignal; 61 | if (typeof alpha === "undefined") alpha = 0.5; 62 | return (alpha * curSignal) + ((1 - alpha) * prevSignal); 63 | }, 64 | 65 | // cached variable to speed up motionTypes 66 | factorCache = [], 67 | 68 | // Options for calculating the parallax effect 69 | // naturally a tangent is used, alternatively a Gaussian cumulative distribution function can be used 70 | motionType = { 71 | linear: function(delta, deltaMax) { 72 | if (delta <= -deltaMax) return 1; 73 | if (delta >= deltaMax) return -1; 74 | return -delta/deltaMax; 75 | }, 76 | natural: function(delta, deltaMax) { 77 | if (delta <= -deltaMax) return 1; 78 | if (delta >= deltaMax) return -1; 79 | if (factorCache['n'+deltaMax] === undefined) factorCache['n'+deltaMax] = Math.tan(deltaMax*0.01745); 80 | return -Math.tan(delta*0.01745) / factorCache['n'+deltaMax]; 81 | }, 82 | performance: function(delta, deltaMax) { 83 | if (delta <= -deltaMax) return 1; 84 | if (delta >= deltaMax) return -1; 85 | if (factorCache['p'+deltaMax] === undefined) factorCache['p'+deltaMax] = (deltaMax/90) + (4.2*Math.pow(deltaMax/90,7)); 86 | return -((delta/90) + (4.2*Math.pow(delta/90,7))) / factorCache['p'+deltaMax]; 87 | }, 88 | gaussian: function(delta, deltaMax) { 89 | return 1 - 2 * gCDFApprox(delta/90, 135/deltaMax); 90 | } 91 | }, 92 | 93 | // Returns a function which adds a vendor prefix to any CSS property name 94 | vendorPrefix = (function() { 95 | var prefixes = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/, 96 | style = $('script')[0].style, 97 | prefix = '', 98 | prop; 99 | 100 | for (prop in style) { 101 | if (prefixes.test(prop)) { 102 | prefix = prop.match(prefixes)[0]; 103 | break; 104 | } 105 | } 106 | 107 | if ('WebkitOpacity' in style) { prefix = 'Webkit'; } 108 | if ('KhtmlOpacity' in style) { prefix = 'Khtml'; } 109 | 110 | return function(property) { 111 | return prefix + (prefix.length > 0 ? property.charAt(0).toUpperCase() + property.slice(1) : property); 112 | }; 113 | }()), 114 | 115 | prefixedTransform = vendorPrefix('transform'), 116 | 117 | supportsBackgroundPositionXY = $('
      ', { style: 'background:#fff' }).css('background-position-x') !== undefined, 118 | 119 | setBackgroundPosition = (supportsBackgroundPositionXY ? 120 | function($element, x, y) { 121 | if($element.attr('data-parallaxify-inverted')) { 122 | x = (parseFloat(x) * -1); 123 | y = (parseFloat(y) * -1); 124 | } 125 | 126 | $element.css({ 127 | 'background-position-x': x, 128 | 'background-position-y': y 129 | }); 130 | } : 131 | function($element, x, y) { 132 | $element.css('background-position', x + ' ' + y); 133 | } 134 | ), 135 | 136 | getBackgroundPosition = (supportsBackgroundPositionXY ? 137 | function($element) { 138 | return [ 139 | $element.css('background-position-x'), 140 | $element.css('background-position-y') 141 | ]; 142 | } : 143 | function($element) { 144 | return $element.css('background-position').split(' '); 145 | } 146 | ), 147 | 148 | // using requestAnimationFrame to limit execution to 149 | // the animation frames and reduce browser load 150 | // fallback to 60x per second 151 | requestAnimationFrame = ( 152 | window.requestAnimationFrame || 153 | window.webkitRequestAnimationFrame || 154 | window.mozRequestAnimationFrame || 155 | window.oRequestAnimationFrame || 156 | window.msRequestAnimationFrame || 157 | function(callback) { 158 | setTimeout(callback, 1000 / maxFPS); 159 | } 160 | ); 161 | 162 | function Plugin(element, options) { 163 | this.element = element; 164 | this.options = $.extend({}, defaults, options); 165 | 166 | this._defaults = defaults; 167 | this._name = pluginName; 168 | 169 | this.init(); 170 | } 171 | 172 | Plugin.prototype = { 173 | init: function() { 174 | this.options.name = pluginName + '_' + Math.floor(Math.random() * 1e9); 175 | this.tilt = { 176 | beta : 0, 177 | gamma : 0 178 | }; 179 | 180 | this._defineElements(); 181 | this._defineGetters(); 182 | this._defineSetters(); 183 | this._detectMobile(); 184 | this._detectMotionType(); 185 | this._detectViewport(); 186 | this._handleWindowLoadAndResize(); 187 | 188 | this.refresh({ firstLoad: true }); 189 | 190 | this._startAnimation(); 191 | }, 192 | _defineElements: function() { 193 | this.$element = ( this.element === document.body || this.element === window ? $('body') : $(this.element) ); 194 | this.$viewportElement = this.options.relativeEl ||$(window); 195 | }, 196 | _defineGetters: function() { 197 | 198 | // define getters 199 | // sensor data and mouse move 200 | // return value is between -1 and +1 201 | 202 | var self = this, 203 | motionTypeAdapter = motionType[self.options.motionType], 204 | mouseMoveAdapter = motionType[self.options.mouseMotionType]; 205 | 206 | this._getMoveHorizontal = function() { 207 | 208 | if (this.useMouseMove && this.clientX !== null && this.clientX !== this.oldClientX ) { 209 | return mouseMoveAdapter( this.options.motionAngleX * (1 - (2*this.clientX/this.viewportWidth)), this.options.motionAngleX); 210 | } 211 | 212 | if (this.useSensor && this.beta !== null && this.gamma !== null) { 213 | // output = 2*gCDFApprox(tilt/180, 0.75*90/(0.5*this.options.motionAngle))-1; 214 | // -180 < tilt < 180 => multiply beta x 2 215 | 216 | // tilt.gamma and tilt.beta 217 | var tilt = this.tilt; 218 | 219 | if (this.viewportLandscape) { 220 | if (this.viewportFlipped) { 221 | // landscape flipped 222 | return motionTypeAdapter(-tilt.beta, this.options.motionAngleX); 223 | } else { 224 | // landscape regular 225 | return motionTypeAdapter(tilt.beta, this.options.motionAngleX); 226 | } 227 | } else { 228 | if (this.viewportFlipped) { 229 | // portrait flipped 230 | return motionTypeAdapter(-tilt.gamma, this.options.motionAngleX); 231 | } else { 232 | // portrait regular 233 | return motionTypeAdapter(tilt.gamma, this.options.motionAngleX); 234 | } 235 | } 236 | } else { 237 | this.useSensor = false; 238 | } 239 | 240 | return mouseMoveAdapter( this.options.motionAngleX * (1 - (2*this.oldClientX/this.viewportWidth)), this.options.motionAngleX); 241 | }; 242 | 243 | this._getMoveVertical = function() { 244 | 245 | if (this.options.useMouseMove && this.clientY !== null && this.clientY !== this.oldClientY ) { 246 | return mouseMoveAdapter( this.options.motionAngleY * (1 - (2*this.clientY/this.viewportHeight)), this.options.motionAngleY); 247 | } 248 | 249 | if (this.useSensor && this.beta !== null && this.gamma !== null) { 250 | 251 | // tilt.gamma and tilt.beta 252 | var tilt = this.tilt; 253 | 254 | if (this.viewportLandscape) { 255 | if (this.viewportFlipped) { 256 | // landscape flipped 257 | return motionTypeAdapter(-tilt.gamma, this.options.motionAngleY); 258 | } else { 259 | // landscape regular 260 | return motionTypeAdapter(tilt.gamma, this.options.motionAngleY); 261 | } 262 | } else { 263 | if (this.viewportFlipped) { 264 | // portrait flipped 265 | return motionTypeAdapter(-tilt.beta, this.options.motionAngleY); 266 | } else { 267 | // portrait regular 268 | return motionTypeAdapter(tilt.beta, this.options.motionAngleY); 269 | } 270 | } 271 | } else { 272 | this.useSensor = false; 273 | } 274 | 275 | return mouseMoveAdapter( this.options.motionAngleY * (1 - (2*this.oldClientY/this.viewportHeight)), this.options.motionAngleY); 276 | }; 277 | 278 | }, 279 | _defineSetters: function() { 280 | 281 | // define setters 282 | // set position of elements 283 | 284 | var self = this, 285 | positionPropertyAdapter = positionProperty[self.options.positionProperty]; 286 | 287 | // use .setPosition or if not available use .setLeft and .setTop 288 | this._setPosition = positionPropertyAdapter.setPosition || 289 | function($element, left, originalLeft, top, originalTop) { 290 | if (self.options.horizontalParallax) { 291 | positionPropertyAdapter.setLeft($element, -left, -originalLeft); 292 | } 293 | if (self.options.verticalParallax) { 294 | positionPropertyAdapter.setTop($element, -top, -originalTop); 295 | } 296 | }; 297 | 298 | }, 299 | refresh: function(options) { 300 | if (!options || !options.firstLoad) { 301 | this._reset(); 302 | } 303 | this._findElements(); 304 | this._findBackgrounds(); 305 | // Fix for WebKit background rendering bug 306 | if (options && options.firstLoad && /WebKit/.test(navigator.userAgent)) { 307 | $(window).load(function() { 308 | var $el = $('body'); 309 | oldLeft = $el.scrollLeft(); 310 | oldTop = $el.scrollTop(); 311 | 312 | $el.scrollLeft(oldLeft + 1); 313 | $el.scrollTop(oldTop + 1); 314 | 315 | $el.scrollLeft(oldLeft); 316 | $el.scrollTop(oldTop); 317 | }); 318 | } 319 | }, 320 | _detectViewport: function() { 321 | this.viewportWidth = this.$viewportElement.width(); 322 | this.viewportHeight = this.$viewportElement.height(); 323 | if (this.useSensor) { 324 | this.viewportFlipped = (window.orientation === 180); 325 | this.viewportLandscape = (Math.abs(window.orientation) === 90); 326 | } 327 | }, 328 | _detectMobile: function() { 329 | // see http://detectmobilebrowser.com/mobile 330 | var browser = navigator.userAgent || navigator.vendor || window.opera; 331 | this.isMobile = (/(bb\d+|meego).+mobile|android|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|playbook|plucker|pocket|psp|series(4|6)0|silk|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(browser)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(browser.substr(0,4))); 332 | }, 333 | _detectMotionType: function() { 334 | this.useSensor = false; 335 | this.useSensorWebkit = false; 336 | this.useSensorMoz = false; 337 | this.useMouseMove = false; 338 | 339 | if (this.options.useGyroscope && (this.isMobile || this.options.inputPriority === 'gyroscope')) { 340 | // Webkit uses deviceorientation (DeviceOrientationEvent) 341 | this.useSensorWebkit = window.DeviceOrientationEvent !== undefined; 342 | // Mozilla uses MozOrientation (OrientationEvent) 343 | this.useSensorMoz = window.OrientationEvent !== undefined; 344 | this.useSensor = this.useSensorWebkit || this.useSensorMoz; 345 | } 346 | if (this.options.useMouseMove && !this.isMobile) { 347 | this.useMouseMove = this.$viewportElement.mousemove !== undefined; 348 | } 349 | }, 350 | _findElements: function() { 351 | var self = this; 352 | 353 | if (this.elements !== undefined) { 354 | for (var i = this.elements.length - 1; i >= 0; i--) { 355 | this.elements[i].$element.data('parallaxify-ElementIsActive', undefined); 356 | } 357 | } 358 | 359 | this.elements = []; 360 | 361 | if(!this.options.parallaxElements) return; 362 | 363 | this.$element.find('[data-parallaxify-range],[data-parallaxify-range-x],[data-parallaxify-range-y]').each(function(i) { 364 | var $this = $(this); 365 | 366 | if (!$this.data('parallaxify-ElementIsActive')) { 367 | $this.data('parallaxify-ElementIsActive', this); 368 | } else if ($this.data('parallaxify-ElementIsActive') !== this) { 369 | return; // stop, because already set previously 370 | } 371 | 372 | // saving/restoring original positions 373 | if (!$this.data('parralaxify-originalLeft')) { 374 | $this.data('parallaxify-originalLeft', $this.css('left')); 375 | $this.data('parallaxify-originalTop', $this.css('top')); 376 | } else { 377 | $this.css('left', $this.data('parallaxify-originalLeft')); 378 | $this.css('top', $this.data('parallaxify-originalTop')); 379 | } 380 | 381 | // adding objects to element collection 382 | self.elements.push({ 383 | $element: $this, 384 | originalPositionLeft: $this.position().left, 385 | originalPositionTop: $this.position().top, 386 | parallaxDistanceX: ($this.data('parallaxify-range-x') !== undefined ? $this.data('parallaxify-range-x') : ($this.data('parallaxify-range') !== undefined ? $this.data('parallaxify-range') : 0)), 387 | parallaxDistanceY: ($this.data('parallaxify-range-y') !== undefined ? $this.data('parallaxify-range-y') : ($this.data('parallaxify-range') !== undefined ? $this.data('parallaxify-range') : 0)), 388 | width: $this.outerWidth(true), 389 | height: $this.outerHeight(true) 390 | }); 391 | }); 392 | }, 393 | _findBackgrounds: function() { 394 | var self = this, 395 | $backgroundElements; 396 | 397 | this.backgrounds = []; 398 | 399 | if(!this.options.parallaxBackgrounds) return; 400 | 401 | $backgroundElements = this.$element.find('[data-parallaxify-background-range],[data-parallaxify-background-range-x],[data-parallaxify-background-range-y]'); 402 | 403 | if (this.$element.data('parallaxify-background-range') || this.$element.data('parallaxify-background-range-x') || this.$element.data('parallaxify-background-range-y')) { 404 | $backgroundElements = $backgroundElements.add(this.$element); 405 | } 406 | 407 | $backgroundElements.each(function() { 408 | var $this = $(this), 409 | backgroundPosition = getBackgroundPosition($this); 410 | 411 | if (!$this.data('parallaxify-backgroundIsActive')) { 412 | $this.data('parallaxify-backgroundIsActive', this); 413 | } else if ($this.data('parallaxify-backgroundIsActive') !== this) { 414 | return; // stop, because already set previously 415 | } 416 | 417 | // saving/restoring original background positions 418 | if (!$this.data('parralaxify-backgroundOriginalLeft')) { 419 | $this.data('parallaxify-backgroundOriginalLeft', backgroundPosition[0]); 420 | $this.data('parallaxify-backgroundOriginalTop', backgroundPosition[1]); 421 | } else { 422 | setBackgroundPosition($this, $this.data('parallaxify-backgroundOriginalLeft'), $this.data('parallaxify-backgroundOriginalTop')); 423 | } 424 | 425 | self.backgrounds.push({ 426 | $element: $this, 427 | originalValueLeft: backgroundPosition[0], 428 | originalValueTop: backgroundPosition[1], 429 | originalBackgroundPositionLeft: (isNaN(parseInt(backgroundPosition[0], 10)) ? 0 : parseInt(backgroundPosition[0], 10)), 430 | originalBackgroundPositionTop: (isNaN(parseInt(backgroundPosition[1], 10)) ? 0 : parseInt(backgroundPosition[1], 10)), 431 | originalPositionLeft: $this.position().left, 432 | originalPositionTop: $this.position().top, 433 | parallaxDistanceX: ($this.data('parallaxify-background-range-x') !== undefined ? $this.data('parallaxify-background-range-x') : ($this.data('parallaxify-background-range') !== undefined ? $this.data('parallaxify-background-range') : 0)), 434 | parallaxDistanceY: ($this.data('parallaxify-background-range-y') !== undefined ? $this.data('parallaxify-background-range-y') : ($this.data('parallaxify-background-range') !== undefined ? $this.data('parallaxify-background-range') : 0)) 435 | }); 436 | }); 437 | }, 438 | _reset: function() { 439 | var element, 440 | originalPositionLeft, 441 | originalPositionTop, 442 | background, 443 | i; 444 | 445 | for (i = this.elements.length - 1; i >= 0; i--) { 446 | element = this.elements[i]; 447 | originalPositionLeft = element.$element.data('parallaxify-originalLeft'); 448 | originalPositionTop = element.$element.data('parallaxify-originalTop'); 449 | 450 | this._setPosition(element.$element, originalPositionLeft, originalPositionLeft, originalPositionTop, originalPositionTop); 451 | 452 | element.$element.data('parallaxify-originalLeft', null).data('parallaxify-originalLeft', null).data('parallaxify-elementIsActive', null).data('parallaxify-backgroundIsActive', null); 453 | } 454 | 455 | for (i = this.backgrounds.length - 1; i >= 0; i--) { 456 | background = this.backgrounds[i]; 457 | 458 | background.$element.data('parallaxify-backgroundOriginalLeft', null).data('parallaxify-backgroundOriginalTop', null).data('parallaxify-backgroundIsActive', null); 459 | 460 | setBackgroundPosition(background.$element, background.originalValueLeft, background.originalValueTop); 461 | } 462 | }, 463 | destroy: function() { 464 | this._reset(); 465 | 466 | if (this.useMouseMove) this.$viewportElement.unbind('mousemove.' + this.name); 467 | if (this.useSensorWebkit) window.removeEventListener('deviceorientation', this._handleSensorWebkit, false); 468 | if (this.useSensorMoz) window.removeEventListener('MozOrientation', this._handleSensorMoz, false); 469 | 470 | $(window).unbind('load.' + this.name).unbind('resize.' + this.name).unbind('orientationchange.' + this.name); 471 | }, 472 | _processSensorData: function() { 473 | 474 | if (!this.useSensor) return; 475 | 476 | // beta is device pitch (moving up - down) 477 | // values are from -90 to 90 478 | // gamma is device roll (moving left right) 479 | // values are from -180 to 180 480 | 481 | var beta = this.beta, 482 | gamma = this.gamma, 483 | deltaBeta = 0, 484 | deltaGamma = 0; 485 | 486 | // counteract some bugs on Android where return values are 270 upon flipping the device 487 | if (beta > 90) beta = beta - 180; 488 | if (gamma > 180) gamma = gamma - 360; 489 | 490 | if (this.initialBeta === undefined && beta !== null) { 491 | this.initialBeta = beta; 492 | if (this.useSensor && this.options.inputPriority === 'gyroscope') { 493 | this.useMouseMove = false; 494 | if (this.useMouseMove) this.$viewportElement.unbind('mousemove.' + this.name); 495 | } 496 | } 497 | 498 | if (this.initialGamma === undefined && gamma !== null) { 499 | this.initialGamma = gamma; 500 | if (this.useSensor && this.options.inputPriority === 'gyroscope') { 501 | this.useMouseMove = false; 502 | if (this.useMouseMove) this.$viewportElement.unbind('mousemove.' + this.name); 503 | } 504 | } 505 | 506 | if (this.options.adjustBasePosition && this.initialGamma !== undefined && this.initialBeta !== undefined) { 507 | 508 | // adjust positions (accepting position out of range to smooth laying device upside down) 509 | if (gamma - this.initialGamma < -180) { 510 | this.initialGamma = lowPassFilter(gamma + 360, this.initialGamma, this.options.alphaPosition); 511 | } else if (gamma - this.initialGamma > 180) { 512 | this.initialGamma = lowPassFilter(gamma - 360, this.initialGamma, this.options.alphaPosition); 513 | } else { 514 | this.initialGamma = lowPassFilter(gamma, this.initialGamma, this.options.alphaPosition); 515 | } 516 | 517 | if (beta - this.initialBeta < -90) { 518 | this.initialBeta = lowPassFilter(beta + 180, this.initialBeta, this.options.alphaPosition); 519 | } else if (beta - this.initialBeta > 90) { 520 | this.initialBeta = lowPassFilter(beta - 180, this.initialBeta, this.options.alphaPosition); 521 | } else { 522 | this.initialBeta = lowPassFilter(beta, this.initialBeta, this.options.alphaPosition); 523 | } 524 | 525 | } 526 | 527 | deltaBeta = (this.initialBeta !== undefined ? beta - this.initialBeta : beta); 528 | deltaGamma = (this.initialGamma !== undefined ? gamma - this.initialGamma : gamma); 529 | 530 | if (deltaBeta > 100) { 531 | deltaBeta = deltaBeta - 180; 532 | } else if (deltaBeta < -100) { 533 | deltaBeta = deltaBeta + 180; 534 | } 535 | 536 | if (deltaGamma > 200) { 537 | deltaGamma = deltaGamma - 360; 538 | } else if (deltaGamma < -200) { 539 | deltaGamma = deltaGamma + 360; 540 | } 541 | 542 | // use low pass filter on signal 543 | deltaBeta = lowPassFilter(deltaBeta, this.tilt.beta, this.options.alphaFilter); 544 | deltaGamma = lowPassFilter(deltaGamma, this.tilt.gamma, this.options.alphaFilter); 545 | 546 | this.tilt.beta = deltaBeta; 547 | this.tilt.gamma = deltaGamma; 548 | 549 | }, 550 | _repositionElements: function() { 551 | var moveHorizontal = this._getMoveHorizontal(), 552 | moveVertical = this._getMoveVertical(), 553 | element, 554 | background, 555 | bgLeft, 556 | bgTop, 557 | newPositionLeft, 558 | newPositionTop, 559 | i; 560 | 561 | if (this.currentMoveHorizontal === moveHorizontal && this.currentMoveVertical === moveVertical && this.currentWidth === this.viewportWidth && this.currentHeight === this.viewportHeight) { 562 | return; 563 | } else { 564 | this.currentMoveHorizontal = moveHorizontal; 565 | this.currentMoveVertical = moveVertical; 566 | this.currentWidth = this.viewportWidth; 567 | this.currentHeight = this.viewportHeight; 568 | } 569 | 570 | // Reposition elements 571 | for (i = this.elements.length - 1; i >= 0; i--) { 572 | element = this.elements[i]; 573 | 574 | // New positions 575 | if (this.options.horizontalParallax) { 576 | newPositionLeft = (moveHorizontal * element.parallaxDistanceX / 2) + element.originalPositionLeft; 577 | } else { 578 | newPositionLeft = element.originalPositionLeft; 579 | } 580 | 581 | if (this.options.verticalParallax) { 582 | newPositionTop = (moveVertical * element.parallaxDistanceY / 2) + element.originalPositionTop; 583 | } else { 584 | newPositionTop = element.originalPositionTop; 585 | } 586 | 587 | this._setPosition(element.$element, newPositionLeft, element.originalPositionLeft, newPositionTop, element.originalPositionTop); 588 | 589 | } 590 | 591 | // Reposition backgrounds 592 | for (i = this.backgrounds.length - 1; i >= 0; i--) { 593 | background = this.backgrounds[i]; 594 | 595 | bgLeft = (this.options.horizontalParallax ? (moveHorizontal * background.parallaxDistanceX / 2) + background.originalBackgroundPositionLeft + 'px' : background.originalValueLeft); 596 | bgTop = (this.options.verticalParallax ? (moveVertical * background.parallaxDistanceY / 2) + background.originalBackgroundPositionTop + 'px' : background.originalValueTop); 597 | 598 | setBackgroundPosition(background.$element, bgLeft, bgTop); 599 | } 600 | }, 601 | _handleWindowLoadAndResize: function() { 602 | var self = this, 603 | $window = $(window); 604 | 605 | if (self.options.responsive) { 606 | $window.bind('load.' + this.name, function() { 607 | self.refresh(); 608 | }); 609 | } 610 | 611 | $window.bind('resize.' + this.name, function() { 612 | self._detectViewport(); 613 | 614 | if (self.options.responsive) { 615 | self.refresh(); 616 | } 617 | }); 618 | 619 | $window.bind('orientationchange.' + this.name, function() { 620 | self._detectViewport(); 621 | 622 | if (self.options.responsive) { 623 | self.refresh(); 624 | } 625 | }); 626 | }, 627 | // self loading function to constantly reposition elements within each animation frame 628 | _startAnimation: function() { 629 | var self = this, 630 | ticking = false; 631 | 632 | this.beta = 0; 633 | this.gamma = 0; 634 | this.clientX = this.oldClientX = Math.round(self.viewportWidth / 2); 635 | this.clientY = this.oldClientY = Math.round(self.viewportHeight / 2); // */ 636 | 637 | var update = function() { 638 | self._processSensorData(); 639 | self._repositionElements(); 640 | ticking = false; 641 | }; 642 | 643 | var requestTick = function() { 644 | if (!ticking) { 645 | requestAnimationFrame(update); 646 | ticking = true; 647 | } 648 | }; 649 | 650 | this._handleSensorWebkit = function(e) { 651 | // gamma is device roll (moving left right) 652 | // values are from -180 to 180 653 | self.gamma = e.gamma; 654 | 655 | // beta is device pitch (moving up - down) 656 | // values are from -90 to 90 657 | self.beta = e.beta; 658 | 659 | requestTick(); 660 | }; 661 | 662 | this._handleSensorMoz = function(e) { 663 | // x is device roll (moving left right) 664 | // values are from -1 to 1 665 | self.gamma = e.x * 180; 666 | 667 | // y is device pitch (moving up - down) 668 | // values are from +1 to -1 669 | self.beta = e.y * -90; 670 | 671 | requestTick(); 672 | }; 673 | 674 | this._handleMouseMove = function(e) { 675 | self.oldClientX = self.clientX; 676 | self.oldClientY = self.clientY; 677 | e.clientX !== undefined ? self.clientX = e.clientX : self.clientX = e.pageX; 678 | e.clientY !== undefined ? self.clientY = e.clientY : self.clientY = e.pageY; 679 | 680 | requestTick(); 681 | }; 682 | 683 | // bind sensor events to updates 684 | if (this.useSensorWebkit) { 685 | window.addEventListener('deviceorientation', self._handleSensorWebkit, false); 686 | } else if (this.useSensorMoz) { 687 | window.addEventListener('MozOrientation', self._handleSensorMoz, false); 688 | } 689 | // bind mouse move event 690 | if (this.useMouseMove) { 691 | this.$viewportElement.bind('mousemove.' + this.name, self._handleMouseMove); 692 | } 693 | 694 | requestTick(); 695 | } 696 | }; 697 | 698 | $.fn[pluginName] = function (options) { 699 | var args = arguments; 700 | if (options === undefined || typeof options === 'object') { 701 | return this.each(function () { 702 | if (!$.data(this, 'plugin_' + pluginName)) { 703 | $.data(this, 'plugin_' + pluginName, new Plugin(this, options)); 704 | } 705 | }); 706 | } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') { 707 | return this.each(function () { 708 | var instance = $.data(this, 'plugin_' + pluginName); 709 | if (instance instanceof Plugin && typeof instance[options] === 'function') { 710 | instance[options].apply(instance, Array.prototype.slice.call(args, 1)); 711 | } 712 | if (options === 'destroy') { 713 | $.data(this, 'plugin_' + pluginName, null); 714 | } 715 | }); 716 | } 717 | }; 718 | 719 | $[pluginName] = function(options) { 720 | var $window = $(window); 721 | return $window[pluginName].apply($window, Array.prototype.slice.call(arguments, 0)); 722 | }; 723 | 724 | // Expose the position property function hashes so they can be extended 725 | $[pluginName].positionProperty = positionProperty; 726 | 727 | // Expose the motion type function hashes so they can be extended 728 | $[pluginName].motionType = motionType; 729 | 730 | // Expose the plugin class so it can be modified 731 | window[pluginName] = Plugin; 732 | }(jQuery, this, document)); -------------------------------------------------------------------------------- /note.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 119 | 120 |
      121 |
      122 | × 123 |
      124 |
      125 |
      126 |
      127 |
      128 |
      Scrobbling!
      129 |
      130 |
      131 |
      132 |
      133 | 134 | -------------------------------------------------------------------------------- /sc.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | set animeFile=%~nx1 3 | dir /b /s "c:\users\%animeFile%" > animepath.txt 4 | set /p animePath= nul 14 | ffmpeg -ss "%rand2%" -i "%animePath%" -f image2 -vframes 1 "%animeFile%_%random%.jpg" > nul 15 | 16 | pause 17 | -------------------------------------------------------------------------------- /version: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.0.7", 3 | "url": "" 4 | } --------------------------------------------------------------------------------