├── README.md ├── LICENSE ├── css ├── badges.css └── bootstrap-responsive.min.css ├── instructions.txt ├── index.html └── js ├── reportcard.coffee ├── reportcard.js └── vendor ├── bootstrap.min.js └── jquery-1.10.1.min.js /README.md: -------------------------------------------------------------------------------- 1 | reportcard 2 | ========== 3 | 4 | This is a Report Card widget for tracking your online coding school progress. 5 | 6 | I started this project after posting about a pretty simple widget I had been working on back when Treehouse only had a facebook group as a forum, to see if anyone else had thought about embedding their "Report Card" on their personal site. Since there seemed to be some stellar interest, I have been working on this current version of the Report Card Widget as a side project for a number of months now. It has finally come together pretty well, and I am excited to announce version 1.0 of the Coding Report Card! 7 | 8 | A full walkthrough of the installation of this report card widget can be found at http://reportcard.rileyh.com/instructions.html -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Riley Hilliard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /css/badges.css: -------------------------------------------------------------------------------- 1 | .report-card { 2 | text-align:center; 3 | } 4 | 5 | .badges { 6 | margin:10px 10px 25px; 7 | padding:0; 8 | } 9 | 10 | .badges li { 11 | display:inline-block; 12 | margin:2px; 13 | } 14 | 15 | .badges li img { 16 | width: 100%; 17 | text-align: center; 18 | -webkit-box-reflect: below 0 -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(70%, transparent), to(rgba(255,255,255,0.2))); 19 | } 20 | 21 | .badges li img:hover { 22 | opacity:.7; 23 | animation:badges 100ms; 24 | -webkit-animation:badges 100ms; 25 | } 26 | 27 | @keyframes badges { 28 | 0% { margin: -17px 2px 0px 0px } 29 | 50% { margin: -27px 2px 0px 0px } 30 | 100% { margin: -17px 2px 0px 0px } 31 | } 32 | @-webkit-keyframes badges /* Safari and Chrome */ { 33 | 0% { margin: -17px 2px 0px 0px } 34 | 50% { margin: -27px 2px 0px 0px } 35 | 100% { margin: -17px 2px 0px 0px } 36 | } 37 | 38 | .spinner { 39 | width: 40px; 40 | height: 40px; 41 | margin: 100px auto; 42 | background-color: #333; 43 | 44 | border-radius: 100%; 45 | -webkit-animation: scaleout 1.0s infinite ease-in-out; 46 | animation: scaleout 1.0s infinite ease-in-out; 47 | } 48 | 49 | @-webkit-keyframes scaleout { 50 | 0% { -webkit-transform: scale(0.0) } 51 | 100% { 52 | -webkit-transform: scale(1.0); 53 | opacity: 0; 54 | } 55 | } 56 | 57 | @keyframes scaleout { 58 | 0% { 59 | transform: scale(0.0); 60 | -webkit-transform: scale(0.0); 61 | } 100% { 62 | transform: scale(1.0); 63 | -webkit-transform: scale(1.0); 64 | opacity: 0; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /instructions.txt: -------------------------------------------------------------------------------- 1 | A full walkthrough of the installation of this report card widget 2 | can be found at http://reportcard.rileyh.com/instructions.html 3 | 4 | 5 | ################################################################################ 6 | MMMMMMMMMMMMMMMMMMMMMMD$I+I7OZZO8DNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 7 | MMMMMMMMMMMMMMMMMMMMOZZZ$7778$ZZOZ8NDNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 8 | MMMMMMMMMMMMMMMMMMMZ88D87Z7?I$Z7?ZIONNDDNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 9 | MMMMMMMMMMMMMMMMMNDO8O8Z$7I??7I$7ZO$Z88NDNDMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 10 | MMMMMMMMMMMMMMMMM8D8OOOZZ$?+=IIZO8OZ$ZZ$ODODNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 11 | MMMMMMMMMMMMMMMMDDNNDDD8DO?7O8OZIII7$7ZZIZ8ONMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 12 | MMMMMMMMMMMMMMMNNNNNDDDNNI7ZOO=~~~::~?O$D8D8DMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 13 | MMMMMMMMMMMMMMMO8ND8DO88DDO7?~~~:::::~+$DDD$INMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 14 | MMMMMMMMMMMMMMMO7MNNO?ZZ$?+=~~::::::~~~=788DDNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 15 | MMMMMMMMMMMMMNOODMMNND88$+===~~~~:::~~==7O8DMNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 16 | MMMMMMMMMMMMMNDDNNMNND8ZI?++=+=====~====I8NNDNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 17 | MMMMMMMMMMMMMMNDM8MMNDOZ$77II?I7ZOOZI??==IONDNDMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 18 | MMMMMMMMMMMMMMMNNMMMNDDD8DNDO=~?$Z7$?I?===Z8NDDNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 19 | MMMMMMMMMMMMNNMMMMMMNNNNN88DN+~~~+7$?~~~=+O8DNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 20 | MMMMMMMMMMMMMMMMMMMMNDNN88ZZ8+:=~~~~~~~~==$$ZZNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 21 | MMMMMMMMMMMMMMMMMMMND8OZ777Z8I~~~=~~~~~~==?:~=NNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 22 | MMMMMMMMMMMMMMMMNMMN8OOZ7IIZO7====~~~~~=====7NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 23 | MMMMMMMMMMMMMMMMMMMMM888Z77ZDMO$O7~~~~~====INMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 24 | MMMMMMMMMMMMMMMMMMMNN8DDOZ$ONNZZ?~~~~~====~=NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 25 | MMMMMMMMMMMMMMMMMMMMMO8D8OZZ8O?+II?+I==~==++MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 26 | MMMMMMMMMMMMMMMMMMMMMM8DD8Z8NMN8O7:=~===+++DNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 27 | MMMMMMMMMMMMMMMMMMMMMND8D8Z$Z8$77$I++=+++?+8MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 28 | MMMMMMMMMMMMMMMMMMMMMMMD8D88OO8OOI====++7I+=MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 29 | MMMMMMMMMMMMMMMMMMMMMMMMDDDD87I?+====+I$I?+=MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 30 | MMMMMMMMMMMMMMMMMMMMMMND8MD8D8Z$77777$$$?++++$Z?MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 31 | MMMMMMMMMMMMMMMMMMMMMMMNMMMMD88888OZOO$I+++==ZI?:MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 32 | MMMMMMMMMMMMMMMMMMMMMNDZMMMMMNDNNNNO7I??+=====::?:$NMMMMMMMMMMMMMMMMMMMMMMMMMMMM 33 | MMMMMMMMMMMMMMMMMMMMM8ZZ87MMNNNNDDO$7I??+====?,,??.+DNMMMMMMMMMMMMMMMMMMMMMMMMMM 34 | MMMMMMMMMMMMMMMMMMMMODDI8I7NNNNNDD8Z7I+++===~7=~=+,++,=MMMNMMMMMMMMMMMMMMMMMMMMM 35 | MMMMMMMMMMMMMMMMMZ?ODOZ7O++ZI88O88O$I??+++===7=,.?.,?:.=+?+8MNMMMMMMMMMMMMMMMMMM 36 | MMMMMMMMMMMMMMMZ$8=Z87D?$MNN$MZ:7$Z77I?+++==?7=?7+,=I:.=I=:+~,,8MMMMMMMMMMMMMMMM 37 | MMMMMMMMMMMM877I+?:7?$OZNNMMNZ8DND?III?==~==?$$7~N7,=?:,7+.=+,:?+:ZMMMMMMMMMMMMM 38 | MMMMMMMMM?7$I~=7~+~$I?$NOODMDNN8888~+++=~==7$78ZO8DO?=.:?=:I7::I+,.,:MMMMMMMMMMM 39 | MMMMMN?=7$~I?=~7I:,II$+$O~:$O?OOI$8O~~====,,~ODZ7$?=DZ=.I+.+I:,=?::.++,MMMMMMMMM 40 | MMMM87=~+~:$7I~7OI:77+=7Z=~7O~I7$=IZ7~~=:::?IZ+:II~,+7I:7I,$?~~I,,?,:+I,ZNMMMMMM 41 | MMM+Z~=I77::?+:=~?,=?::,?Z,,?7:II,,$Z==,?IZDD7:,?+,,=++.++,II~+I::II,.++,?NMMMMM 42 | MN=$7:~??,~~~77:=7:,++::I$+:?$:++,~,I777ND$I77~~77~:III:??.++,~?,,=++.,II,+MMMMM 43 | M7IOZ+?$$~~,~~$?$I+:7I~~:7$:,7=:IM.~7IO8Z?~I7:,:II..++=:??~7I:+=,,:7II:?I:=NMMMM 44 | ZI?Z$::II,~I,:?$?I?,?+~,,??:,+?:=??,?=:??~:?I,,,?I,,+?:,+?.7?,=??~~:I+,,++,?MMMM 45 | O?+O8==$I,,??~:O?$7:777::7I++~7?:??:$:~7?==7$~~?77~:I7::$7,?$,,+$~,,++,:77:IMMMM 46 | O$I8O+=$Z?~=7+.Z+I?::77:~+?I::I+=7IZI:~7I?~7I,.???,,?+,,II~IZ==I7?,:II=::7~I$MMM 47 | OO=7$~?$+7:~$$:O=:I~,I??,:??::?.:II7=,,?I=,II,,+I::~??.,I?:=I?==$Z~=~I+:=I+:~MMM 48 | Z8II8Z?=ON?:I7:8?+Z$~=77~~$$=:$:,??$?~:II?~Z$=~I$==+$$~~$$,=I?~=7$7,:8?::7$,=NMM 49 | ZD?=ZO+I=7$?I$:8$IZZ=,:+=:+I?,=?~~7$7~~$I?~$I=~II,+$$I~:87?IO?~+=ZI?7$I:~77~7NMM 50 | ODN?,$Z~=Z+,:I$DZ7=??::I?:,??::?,,7I?,,I+=:$+~,++,,I?::D=7ZIN?+IZ$:,,?I:,7+,?IMM 51 | I8DNDZI=++8?:I7OO?ID$=+$$~=$$+=O~,I?+,:I??IZ~=IOZ=:ZDI~D$ONN+=?7=I,,:77::II~?,MM 52 | 778DIDD$:=ZD==Z$D88DZ=+$O::=??,Z$~Z$:~:~$IZZ~:$II++$Z+$Z7+?O~:?Z7$I+=$$~:+7~I~MM 53 | O:~8D==MD~+I7:I788OO7:~I7:,:II,+I:$78=:?$+$7:=$I?~:77==Z7:+Z=ZZ:~77::I?,,:7::+MM 54 | Z$=7Z$77$MZ7+I~+$8DDO+=OZZ~=ZZ~7Z:77?~:II+$Z=IOZI?I$$::O$++$$D~~~II:,+7=+I7~:?7M 55 | O8$7I=,~$?:$Z=+$7ZN8O?++OO+?OO?IO7Z$?==7$7ZZ=788ZIO8O==$$$87ZZ~:~7?~~7$==?7=~$:M 56 | $8Z8Z8+~7Z$~=N?7OZZOZ~:,OI:~7$=+Z$$$I==$II$7~=O$7+7II~=OZ+$Z8O~:~7I~:II::,?+:I~M -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Report Card 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 58 | 59 |
60 | 61 | 62 |
63 |

Treehouse Badges Widget

64 |

Welcome to the open source Report Card widget! Right now this project is only compatible with Treehouse. More coding schools may be added in the future if there is enough demand.

65 |

InstructionsDownload via GitHub »

66 | 67 |
68 | 69 | 70 |

Treehouse

71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | 91 |
92 |

Code School

93 | 94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | 114 |
115 | 116 | 119 | 120 |
121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /js/reportcard.coffee: -------------------------------------------------------------------------------- 1 | # github.com/paulirish/jquery-ajax-localstorage-cache 2 | # dependent on Modernizr's localStorage test 3 | $.ajaxPrefilter (options, originalOptions, jqXHR) -> 4 | # Cache it ? 5 | # Modernizr.localstorage, version 3 12/12/13 6 | 7 | hasLocalStorage = -> 8 | mod = 'modernizr' 9 | try 10 | localStorage.setItem mod, mod 11 | localStorage.removeItem mod 12 | return true 13 | catch e 14 | return false 15 | return 16 | 17 | if !hasLocalStorage() or !options.localCache 18 | return 19 | hourstl = options.cacheTTL or 5 20 | cacheKey = options.cacheKey or options.url.replace(/jQuery.*/, '') + options.type + (options.data or '') 21 | # isCacheValid is a function to validate cache 22 | if options.isCacheValid and !options.isCacheValid() 23 | localStorage.removeItem cacheKey 24 | # if there's a TTL that's expired, flush this item 25 | ttl = localStorage.getItem(cacheKey + 'cachettl') 26 | if ttl and ttl < +new Date 27 | localStorage.removeItem cacheKey 28 | localStorage.removeItem cacheKey + 'cachettl' 29 | ttl = 'expired' 30 | value = localStorage.getItem(cacheKey) 31 | if value 32 | #In the cache? So get it, apply success callback & abort the XHR request 33 | # parse back to JSON if we can. 34 | if options.dataType.indexOf('json') == 0 35 | value = JSON.parse(value) 36 | options.success value 37 | # Abort is broken on JQ 1.5 :( 38 | jqXHR.abort() 39 | else 40 | #If it not in the cache, we change the success callback, just put data on localstorage and after that apply the initial callback 41 | if options.success 42 | options.realsuccess = options.success 43 | 44 | options.success = (data) -> 45 | strdata = data 46 | if @dataType.indexOf('json') == 0 47 | strdata = JSON.stringify(data) 48 | # Save the data to localStorage catching exceptions (possibly QUOTA_EXCEEDED_ERR) 49 | try 50 | localStorage.setItem cacheKey, strdata 51 | catch e 52 | # Remove any incomplete data that may have been saved before the exception was caught 53 | localStorage.removeItem cacheKey 54 | localStorage.removeItem cacheKey + 'cachettl' 55 | if options.cacheError 56 | options.cacheError e, cacheKey, strdata 57 | if options.realsuccess 58 | options.realsuccess data 59 | return 60 | 61 | # store timestamp 62 | if !ttl or ttl == 'expired' 63 | localStorage.setItem cacheKey + 'cachettl', +new Date + 1000 * 60 * 60 * hourstl 64 | return 65 | 66 | 67 | ### Reportcard.js ### 68 | # github.com/rileyhilliard/reportcard 69 | (($) -> 70 | $.fn.reportCard = (options) -> 71 | toThousands = (x)-> 72 | return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") 73 | 74 | class ReportCard 75 | constructor: (params) -> 76 | {@userName, @site, @badgesAmount, @tooltips} = params 77 | 78 | #Build HTML object 79 | build: (data)-> 80 | 81 | lastBadges = data.badges[-(options.badgesAmount)..] 82 | liWidth = (100 / (lastBadges.length + 1)) + "%" 83 | 84 | # HTML Generator 85 | html = """ 86 |

I have passed #{data.badge_count} lessons and scored #{toThousands(data.points_total)} points at #{data.site}!

87 |

Check out some of my last passed course content at the badges below:

88 | " 101 | 102 | # print generated HTML to page 103 | options.$element.html(html) 104 | 105 | # If Tooltips, call bootstrap tooltip plugin 106 | if options.tooltips 107 | options.$element.each (i, el)-> 108 | $(el).find('li').tooltip() 109 | return 110 | 111 | # Default data transform 112 | transform: (data)-> 113 | return data 114 | 115 | # Data AJAX caller 116 | getData: (opts)-> 117 | $this = this 118 | $.ajax 119 | type: "GET" 120 | url: @url 121 | localCache: true 122 | cacheTTL: 0.5 123 | cacheKey: 'reportcard'+options.site+options.userName 124 | dataType: opts.dataType 125 | crossDomain: true 126 | async: true 127 | beforeSend: -> 128 | # Add loading Gif 129 | options.$element.html('
') 130 | return 131 | success: (data) -> 132 | # transform data, then build widget 133 | return $this.build($this.transform(data)) 134 | 135 | # Treehosue class 136 | class Treehouse extends ReportCard 137 | constructor: (params)-> 138 | super(params) 139 | @url = "https://teamtreehouse.com/" + @userName + ".json" 140 | 141 | getData: -> 142 | super({dataType:'json'}) 143 | 144 | transform: (data)-> 145 | return { 146 | site: "Treehouse" 147 | username: data.profile_name 148 | profile_url: data.profile_url 149 | points: data.points 150 | points_total: data.points.total 151 | badge_count: data.badges.length 152 | badges: data.badges.map (badge)-> 153 | return { 154 | courses: badge.courses 155 | course_count: badge.courses.length 156 | earned_date: Date.parse(badge.earned_date) 157 | icon_url: badge.icon_url 158 | label: badge.name 159 | url: badge.url 160 | } 161 | } 162 | 163 | # CodeSchool Class 164 | class Codeschool extends ReportCard 165 | constructor: (params)-> 166 | super(params) 167 | @url = "https://www.codeschool.com/users/" + @userName + ".json"; 168 | 169 | getData: -> 170 | super({dataType:'jsonp'}) 171 | 172 | transform: (data)-> 173 | return { 174 | site: "Code School" 175 | username: data.user.username 176 | profile_url: 'https://www.codeschool.com/users/' + data.user.username 177 | points: undefined 178 | points_total: data.user.total_score 179 | badge_count: data.badges.length 180 | badges: data.badges.map (badge)-> 181 | return { 182 | courses: undefined 183 | course_count: undefined 184 | earned_date: undefined 185 | icon_url: badge.badge 186 | label: badge.name 187 | url: badge.course_url 188 | } 189 | } 190 | 191 | # Init 192 | options.$element = this 193 | options.badgesAmount = if options.badgesAmount then options.badgesAmount else 5 194 | if !options.userName then alert('You need to pass in a username') 195 | if !options.site then alert('You need to pass in a site') 196 | 197 | if options.site == "treehouse" 198 | th = new Treehouse options 199 | th.getData() 200 | else if options.site == "codeschool" 201 | cs = new Codeschool options 202 | cs.getData() 203 | 204 | ) jQuery 205 | -------------------------------------------------------------------------------- /js/reportcard.js: -------------------------------------------------------------------------------- 1 | var __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, 2 | __hasProp = {}.hasOwnProperty; 3 | 4 | $.ajaxPrefilter(function(options, originalOptions, jqXHR) { 5 | var cacheKey, hasLocalStorage, hourstl, ttl, value; 6 | hasLocalStorage = function() { 7 | var e, mod; 8 | mod = 'modernizr'; 9 | try { 10 | localStorage.setItem(mod, mod); 11 | localStorage.removeItem(mod); 12 | return true; 13 | } catch (_error) { 14 | e = _error; 15 | return false; 16 | } 17 | }; 18 | if (!hasLocalStorage() || !options.localCache) { 19 | return; 20 | } 21 | hourstl = options.cacheTTL || 5; 22 | cacheKey = options.cacheKey || options.url.replace(/jQuery.*/, '') + options.type + (options.data || ''); 23 | if (options.isCacheValid && !options.isCacheValid()) { 24 | localStorage.removeItem(cacheKey); 25 | } 26 | ttl = localStorage.getItem(cacheKey + 'cachettl'); 27 | if (ttl && ttl < +(new Date)) { 28 | localStorage.removeItem(cacheKey); 29 | localStorage.removeItem(cacheKey + 'cachettl'); 30 | ttl = 'expired'; 31 | } 32 | value = localStorage.getItem(cacheKey); 33 | if (value) { 34 | if (options.dataType.indexOf('json') === 0) { 35 | value = JSON.parse(value); 36 | } 37 | options.success(value); 38 | jqXHR.abort(); 39 | } else { 40 | if (options.success) { 41 | options.realsuccess = options.success; 42 | } 43 | options.success = function(data) { 44 | var e, strdata; 45 | strdata = data; 46 | if (this.dataType.indexOf('json') === 0) { 47 | strdata = JSON.stringify(data); 48 | } 49 | try { 50 | localStorage.setItem(cacheKey, strdata); 51 | } catch (_error) { 52 | e = _error; 53 | localStorage.removeItem(cacheKey); 54 | localStorage.removeItem(cacheKey + 'cachettl'); 55 | if (options.cacheError) { 56 | options.cacheError(e, cacheKey, strdata); 57 | } 58 | } 59 | if (options.realsuccess) { 60 | options.realsuccess(data); 61 | } 62 | }; 63 | if (!ttl || ttl === 'expired') { 64 | localStorage.setItem(cacheKey + 'cachettl', +(new Date) + 1000 * 60 * 60 * hourstl); 65 | } 66 | } 67 | }); 68 | 69 | 70 | /* Reportcard.js */ 71 | 72 | (function($) { 73 | return $.fn.reportCard = function(options) { 74 | var Codeschool, ReportCard, Treehouse, cs, th, toThousands; 75 | toThousands = function(x) { 76 | return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); 77 | }; 78 | ReportCard = (function() { 79 | function ReportCard(params) { 80 | this.userName = params.userName, this.site = params.site, this.badgesAmount = params.badgesAmount, this.tooltips = params.tooltips; 81 | } 82 | 83 | ReportCard.prototype.build = function(data) { 84 | var html, lastBadges, liWidth; 85 | lastBadges = data.badges.slice(-options.badgesAmount); 86 | liWidth = (100 / (lastBadges.length + 1)) + "%"; 87 | html = "

I have passed " + data.badge_count + " lessons and scored " + (toThousands(data.points_total)) + " points at " + data.site + "!

\n

Check out some of my last passed course content at the badges below:

\n"; 92 | options.$element.html(html); 93 | if (options.tooltips) { 94 | options.$element.each(function(i, el) { 95 | return $(el).find('li').tooltip(); 96 | }); 97 | } 98 | }; 99 | 100 | ReportCard.prototype.transform = function(data) { 101 | return data; 102 | }; 103 | 104 | ReportCard.prototype.getData = function(opts) { 105 | var $this; 106 | $this = this; 107 | return $.ajax({ 108 | type: "GET", 109 | url: this.url, 110 | localCache: true, 111 | cacheTTL: 0.5, 112 | cacheKey: 'reportcard' + options.site + options.userName, 113 | dataType: opts.dataType, 114 | crossDomain: true, 115 | async: true, 116 | beforeSend: function() { 117 | options.$element.html('
'); 118 | }, 119 | success: function(data) { 120 | return $this.build($this.transform(data)); 121 | } 122 | }); 123 | }; 124 | 125 | return ReportCard; 126 | 127 | })(); 128 | Treehouse = (function(_super) { 129 | __extends(Treehouse, _super); 130 | 131 | function Treehouse(params) { 132 | Treehouse.__super__.constructor.call(this, params); 133 | this.url = "https://teamtreehouse.com/" + this.userName + ".json"; 134 | } 135 | 136 | Treehouse.prototype.getData = function() { 137 | return Treehouse.__super__.getData.call(this, { 138 | dataType: 'json' 139 | }); 140 | }; 141 | 142 | Treehouse.prototype.transform = function(data) { 143 | return { 144 | site: "Treehouse", 145 | username: data.profile_name, 146 | profile_url: data.profile_url, 147 | points: data.points, 148 | points_total: data.points.total, 149 | badge_count: data.badges.length, 150 | badges: data.badges.map(function(badge) { 151 | return { 152 | courses: badge.courses, 153 | course_count: badge.courses.length, 154 | earned_date: Date.parse(badge.earned_date), 155 | icon_url: badge.icon_url, 156 | label: badge.name, 157 | url: badge.url 158 | }; 159 | }) 160 | }; 161 | }; 162 | 163 | return Treehouse; 164 | 165 | })(ReportCard); 166 | Codeschool = (function(_super) { 167 | __extends(Codeschool, _super); 168 | 169 | function Codeschool(params) { 170 | Codeschool.__super__.constructor.call(this, params); 171 | this.url = "https://www.codeschool.com/users/" + this.userName + ".json"; 172 | } 173 | 174 | Codeschool.prototype.getData = function() { 175 | return Codeschool.__super__.getData.call(this, { 176 | dataType: 'jsonp' 177 | }); 178 | }; 179 | 180 | Codeschool.prototype.transform = function(data) { 181 | return { 182 | site: "Code School", 183 | username: data.user.username, 184 | profile_url: 'https://www.codeschool.com/users/' + data.user.username, 185 | points: void 0, 186 | points_total: data.user.total_score, 187 | badge_count: data.badges.length, 188 | badges: data.badges.map(function(badge) { 189 | return { 190 | courses: void 0, 191 | course_count: void 0, 192 | earned_date: void 0, 193 | icon_url: badge.badge, 194 | label: badge.name, 195 | url: badge.course_url 196 | }; 197 | }) 198 | }; 199 | }; 200 | 201 | return Codeschool; 202 | 203 | })(ReportCard); 204 | options.$element = this; 205 | options.badgesAmount = options.badgesAmount ? options.badgesAmount : 5; 206 | if (!options.userName) { 207 | alert('You need to pass in a username'); 208 | } 209 | if (!options.site) { 210 | alert('You need to pass in a site'); 211 | } 212 | if (options.site === "treehouse") { 213 | th = new Treehouse(options); 214 | return th.getData(); 215 | } else if (options.site === "codeschool") { 216 | cs = new Codeschool(options); 217 | return cs.getData(); 218 | } 219 | }; 220 | })(jQuery); 221 | 222 | // --- 223 | // generated by coffee-script 1.9.0 224 | -------------------------------------------------------------------------------- /css/bootstrap-responsive.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.3.2 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} 10 | -------------------------------------------------------------------------------- /js/vendor/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap.js by @fat & @mdo 3 | * Copyright 2012 Twitter, Inc. 4 | * http://www.apache.org/licenses/LICENSE-2.0.txt 5 | */ 6 | !function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()};var r=e.fn.alert;e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e.fn.alert.noConflict=function(){return e.fn.alert=r,this},e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")};var n=e.fn.button;e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e.fn.button.noConflict=function(){return e.fn.button=n,this},e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},getActiveIndex:function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},to:function(t){var n=this.getActiveIndex(),r=this;if(t>this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle(!0)),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(".dropdown-backdrop").remove(),e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||("ontouchstart"in document.documentElement&&e('