├── javascripts ├── sxsw.css ├── question_selections.js ├── mustache.js └── sxsw.js ├── images ├── ic_twgeo.png └── twitteratsxsw.png ├── README ├── index.html └── stylesheets └── sxsw.css /javascripts/sxsw.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/ic_twgeo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bs/pleasejobme/master/images/ic_twgeo.png -------------------------------------------------------------------------------- /images/twitteratsxsw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bs/pleasejobme/master/images/twitteratsxsw.png -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | A project by Britt Selvitelle, Kevin Cheng, and Patrick Ewing to help people connect with Twitter Employees at SxSW. -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | twitter @ SxSW 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 26 | 27 | 32 | 33 | 34 |
35 | 36 | 41 | 42 | -------------------------------------------------------------------------------- /stylesheets/sxsw.css: -------------------------------------------------------------------------------- 1 | /* 2 | header and selected nav: #72B1CD 3 | second bar: #C2DEEF 4 | unselected nav text: #2377BB 5 | "sign in with twitter": ##2377BB 6 | sign in now bg: #F2F7FA (btn is actually same as mobile.twitter's 7 | "sign in now": #2377BB 8 | */ 9 | 10 | * { 11 | margin: 0; 12 | padding: 0; 13 | } 14 | 15 | body { 16 | font-size: 16px; 17 | font-family: Gill, Helvetica, sans-serif; 18 | } 19 | 20 | h2, h3 { 21 | font-weight: normal; 22 | margin-left: 4px; 23 | } 24 | 25 | a { 26 | text-decoration: none; 27 | font-weight: thin; 28 | color: #2377BB; 29 | } 30 | 31 | img { 32 | border: 0; 33 | } 34 | 35 | .banner { 36 | padding: 10px 0; 37 | vertical-align: center; 38 | margin: 0 auto; 39 | text-align: center; 40 | } 41 | 42 | #top { 43 | background: #72B1CD; 44 | font-size: 12px; 45 | } 46 | 47 | #navbar { 48 | background: #C2DEEF; 49 | font-size: 15px; 50 | } 51 | 52 | #navbar a { 53 | padding: 0.3em 0.5em; 54 | margin-right: 0.8em; 55 | } 56 | 57 | #navbar a.current { 58 | background: #72B1CD; 59 | color: white; 60 | } 61 | 62 | #map_canvas { 63 | height: 300px; 64 | } 65 | 66 | /* InfoWindows */ 67 | 68 | .image-td { 69 | vertical-align: top; 70 | } 71 | 72 | .tweetUserPopup .profile-pic { 73 | float: left; 74 | margin-right: 6px; 75 | } 76 | 77 | .tweetUserPopup .full-name { 78 | color: #0073AB; 79 | } 80 | 81 | .screen-name { 82 | color: #17B1C8; 83 | } 84 | 85 | .tweet-text { 86 | color: #4D4D4D; 87 | margin-top: 2px; 88 | max-width: 350; 89 | padding: 0; 90 | font-size: 13px; 91 | } 92 | 93 | .created-at { 94 | color: #737373; 95 | } 96 | 97 | /* Questionnaire */ 98 | 99 | #who_should_i_meet #navbar { 100 | background: #C2DEEF; 101 | color: #666; 102 | font-size: 15px; 103 | } 104 | 105 | #who_should_i_meet #navbar .inner { 106 | text-align: left; 107 | max-width: 500px; 108 | padding: 0 8px; 109 | margin: 0 auto; 110 | } 111 | 112 | #questionnaire li { 113 | border: 2px solid #dadada; 114 | color: #2377BB; 115 | letter-spacing: -0.1px; 116 | display: inline-block; 117 | font-size: 12px; 118 | padding: 3px 8px; 119 | margin: 3px 7px; 120 | } 121 | 122 | #questionnaire li:hover { 123 | cursor: pointer; 124 | } 125 | 126 | #questionnaire li.selected { 127 | background: #72B1CD; 128 | border: 2px solid #72B1CD; 129 | color: white; 130 | } 131 | 132 | #questionnaire h3 { 133 | color: #666; 134 | font-size: 16px; 135 | margin: 12px 0 6px 8px; 136 | } 137 | 138 | .twitter-person { 139 | background: #F5F5F5; 140 | color: #666; 141 | min-height: 55px; 142 | line-height: 1.3em; 143 | font-size: 13px; 144 | padding: 6px; 145 | margin: 4px; 146 | width: auto; 147 | } 148 | 149 | .twitter-person .profile-image { 150 | display: inline; 151 | float: left; 152 | margin: 3px 11px 6px 3px; 153 | height: 38px; 154 | width: 38px; 155 | } 156 | 157 | .twitter-person .role { 158 | color: #cccccc; 159 | margin-bottom: 6px; 160 | font-size: 14px; 161 | } 162 | 163 | .twitter-person .person-link { 164 | font-size: 18px; 165 | } 166 | 167 | .twitter-person .meta { 168 | color: #999999; 169 | } 170 | 171 | .twitter-person .meta span { 172 | color: #444; 173 | margin-right: 5px; 174 | } 175 | 176 | #donebutton { 177 | -moz-border-radius: 0.4em; 178 | -webkit-border-radius: 0.4em; 179 | background: #efefef; 180 | border: 1px solid gray; 181 | cursor:pointer; 182 | width: auto; 183 | padding: 6px 10px; 184 | text-align: center; 185 | margin: 8px 6px; 186 | } 187 | 188 | #donebutton.disabled { 189 | border: none; 190 | cursor:default; 191 | color: #ffffff ; 192 | } 193 | 194 | #donebutton.disabled a { 195 | cursor: default; 196 | color: #dadada ; 197 | } 198 | -------------------------------------------------------------------------------- /javascripts/question_selections.js: -------------------------------------------------------------------------------- 1 | /*jslint white: false */ 2 | 3 | var questionSelections = [ 4 | [ 'Which of these sound like awesome things to work on?', 5 | [ { id: 'sexy', name: 'Making fast and sexy applications', people: ['Zhanna', 'trammell', 'k', 'bs', 'hoverbird', 'kevinthau']}, 6 | { id: 'realtimepartners', name: 'Partnering with Twitter', people: ['jess', 'elizabeth', 'rsarver']}, 7 | { id: 'scaling', name: 'Scaling for millions of people', people: ['netik', 'bs', 'hoverbird', 'rsarver'] }, 8 | { id: 'communication', name: 'Changing the way we communicate', people: ['jennadawn', 'sg', 'bs', 'k', 'rsarver']}, 9 | { id: 'journalism', name: 'Transforming journalism', people: ['ChloeS', 'robinsloan', 'jennadawn', 'sg']}, 10 | { id: 'usersupport', name: 'Supporting a global audience', people: ['crystal', 'ed', 'trammell']}, 11 | { id: 'internalops', name: 'Building tools for Twitter & partners', people: ['pandemona', 'stirman', 'bs', 'rsarver', 'jess', 'netik']}, 12 | { id: 'patterns', name: 'Seeing patterns in a sea of data', people: ['kevinweil', 'stirman', 'k', 'zhanna']}, 13 | { id: 'predictingcatastrophe', name: "Predicting catastrophes", people: ['delbius', 'netik', 'bakari']} 14 | ] 15 | ] 16 | ]; 17 | 18 | var twitterPeopleMetadata = { 19 | 'hoverbird': { 20 | role: "Software Engineer, Web Client Team", 21 | info: 'Our agile development process. Building the most used Twitter client. Frontend engineering positions. Boardgames, not basketball.' 22 | }, 23 | 24 | 'bs': { 25 | role: "Tech Lead, Web Client Team", 26 | info: "Working at Twitter to create beauty in web applications. How we're innovating Twitter.com. The backend of the frontend; the frontend of the backend. Passion and craftsmanship in software development. Global hacking. My dog. Greg's mom." 27 | }, 28 | 29 | 'k': { 30 | role : "Product Manager, Web Client Team", 31 | info : 'Product development process at Twitter; Frontend engineering and product manager opportunities; Good spots for BBQ in Austin; How to rock SxSW.' 32 | }, 33 | 34 | 'jess': { 35 | role: "Corporate Development", 36 | info: "Integrating your business withTwitter." 37 | }, 38 | 39 | 'jennadawn': { 40 | role: "Communications", 41 | info: " Embodying the spirit and the voice of Twitter through marketing and comms. SxSW newbie!" 42 | }, 43 | 44 | 'stirman': { 45 | role: "Internal Tools", 46 | info: "Data visualization, project management, internal tools, code that makes art, University of Texas Football!" 47 | }, 48 | 49 | 'ChloeS': { 50 | role: "Media Partnerships", 51 | info: "I collaborate with our news, TV, entertainment & sports partners to create captivating interactive media experiences. Talk to me about curation back-end tools, front-end data viz, how to make live events awesomer, & Twitter's power to flock and amplify your audience." 52 | }, 53 | 54 | 'elizabeth': { 55 | role: "Corporate Development", 56 | info: "Talk to me about your business can integrate with Twitter. Looking to meet awesome companies in the Twittersphere. And, always on the hunt for awesome folks to join our Twitter team." 57 | }, 58 | 59 | 'SG': { 60 | role: "Communications", 61 | info: "New-ish Twitter communications lead. Let's talk media folks. And, looking to build a remarkable comms team. Likes chilaquiles and Shiner." 62 | }, 63 | 64 | 'kevinweil': { 65 | role: "Analytics", 66 | info: "Twitter analytics, data visualization, hadoop, engineering process, being multi-disciplinary at Twitter, company culture, hiring great people." 67 | }, 68 | 69 | 'trammell': { 70 | role: "Design research.", 71 | info: "My eighth-straight SxSW." 72 | }, 73 | 74 | 'Zhanna': { 75 | role: "UX Design, Webclient", 76 | info: "Design; UX strategy at Twitter." 77 | }, 78 | 79 | 'Bakari': { 80 | role: "Legal", 81 | info: "Business and legal affairs. Legal jujitsu such as partnerships in the media, music, geo and platform space." 82 | }, 83 | 84 | 'netik': { 85 | role: "Operations", 86 | info: "How we grow Twitter and its server farm to support millions of users daily, all while avoiding the fail whale. I'm looking for great people to join our Operations team." 87 | }, 88 | 89 | 'delbius': { 90 | role: "Trust and Safety", 91 | info: "Legalities, policy, abuse, and security. Expecting and planning for the worst. Also, the art of always checking your email." 92 | }, 93 | 94 | 'crystal': { 95 | role: "Support", 96 | info: 'Building intuitive, scalable self help systems for people using Twitter.' 97 | }, 98 | 99 | 'pandemona': { 100 | role: "Support tools", 101 | info: 'Engineering at Twitter, internal tools, video games, Canadians!' 102 | }, 103 | 104 | 'ev': { 105 | role: "CEO", 106 | info: 'Twitter.' 107 | }, 108 | 109 | 'kevinthau': { 110 | role: "Mobile", 111 | info: 'Twitter on mobile platforms.' 112 | }, 113 | 114 | 'rsarver': { 115 | role: "Platform", 116 | info: "Community building, integrating Twitter into websites and apps, building tools for developers, the firehose, the API roadmap, the Chirp conference." 117 | }, 118 | 119 | 'robinsloan': { 120 | role: "Media Partnerships", 121 | info: "The intersection of Twitter and media. Ideas and tools that help media companies use the power of Twitter to improve and accelerate everything they do. Brunch at Moonshine." 122 | } 123 | }; 124 | -------------------------------------------------------------------------------- /javascripts/mustache.js: -------------------------------------------------------------------------------- 1 | /* 2 | Shameless port of http://github.com/defunkt/mustache 3 | by Jan Lehnardt , 4 | Alexander Lang , 5 | Sebastian Cohnen 6 | 7 | Thanks @defunkt for the awesome code. 8 | 9 | See http://github.com/defunkt/mustache for more info. 10 | */ 11 | 12 | var Mustache = function() { 13 | var Renderer = function() {}; 14 | 15 | Renderer.prototype = { 16 | otag: "{{", 17 | ctag: "}}", 18 | pragmas: {}, 19 | buffer: [], 20 | pragmas_parsed: false, 21 | 22 | render: function(template, context, partials, in_recursion) { 23 | // fail fast 24 | if(template.indexOf(this.otag) == -1) { 25 | if(in_recursion) { 26 | return template; 27 | } else { 28 | this.send(template); 29 | return; 30 | } 31 | } 32 | 33 | if(!in_recursion) { 34 | this.buffer = []; 35 | } 36 | 37 | if(!this.pragmas_parsed) { 38 | template = this.render_pragmas(template); 39 | } 40 | var html = this.render_section(template, context, partials); 41 | if(in_recursion) { 42 | return this.render_tags(html, context, partials, in_recursion); 43 | } 44 | 45 | this.render_tags(html, context, partials, in_recursion); 46 | }, 47 | 48 | /* 49 | Sends parsed lines 50 | */ 51 | send: function(line) { 52 | if(line != "") { 53 | this.buffer.push(line); 54 | } 55 | }, 56 | 57 | /* 58 | Looks for %PRAGMAS 59 | */ 60 | render_pragmas: function(template) { 61 | this.pragmas_parsed = true; 62 | // no pragmas 63 | if(template.indexOf(this.otag + "%") == -1) { 64 | return template; 65 | } 66 | 67 | var that = this; 68 | var regex = new RegExp(this.otag + "%([\\w_-]+) ?([\\w]+=[\\w]+)?" 69 | + this.ctag); 70 | return template.replace(regex, function(match, pragma, options) { 71 | that.pragmas[pragma] = {}; 72 | if(options) { 73 | var opts = options.split("="); 74 | that.pragmas[pragma][opts[0]] = opts[1]; 75 | } 76 | return ""; 77 | // ignore unknown pragmas silently 78 | }); 79 | }, 80 | 81 | /* 82 | Tries to find a partial in the global scope and render it 83 | */ 84 | render_partial: function(name, context, partials) { 85 | if(typeof(context[name]) != "object") { 86 | throw({message: "subcontext for '" + name + "' is not an object"}); 87 | } 88 | if(!partials || !partials[name]) { 89 | throw({message: "unknown_partial '" + name + "'"}); 90 | } 91 | return this.render(partials[name], context[name], partials, true); 92 | }, 93 | 94 | /* 95 | Renders boolean and enumerable sections 96 | */ 97 | render_section: function(template, context, partials) { 98 | if(template.indexOf(this.otag + "#") == -1) { 99 | return template; 100 | } 101 | var that = this; 102 | // CSW - Added "+?" so it finds the tighest bound, not the widest 103 | var regex = new RegExp(this.otag + "\\#(.+)" + this.ctag + 104 | "\\s*([\\s\\S]+?)" + this.otag + "\\/\\1" + this.ctag + "\\s*", "mg"); 105 | 106 | // for each {{#foo}}{{/foo}} section do... 107 | return template.replace(regex, function(match, name, content) { 108 | var value = that.find(name, context); 109 | if(that.is_array(value)) { // Enumerable, Let's loop! 110 | return that.map(value, function(row) { 111 | return that.render(content, that.merge(context, 112 | that.create_context(row)), partials, true); 113 | }).join(""); 114 | } else if(value) { // boolean section 115 | return that.render(content, context, partials, true); 116 | } else { 117 | return ""; 118 | } 119 | }); 120 | }, 121 | 122 | /* 123 | Replace {{foo}} and friends with values from our view 124 | */ 125 | render_tags: function(template, context, partials, in_recursion) { 126 | // tit for tat 127 | var that = this; 128 | 129 | var new_regex = function() { 130 | return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\/#]+?)\\1?" + 131 | that.ctag + "+", "g"); 132 | }; 133 | 134 | var regex = new_regex(); 135 | var lines = template.split("\n"); 136 | for (var i=0; i < lines.length; i++) { 137 | lines[i] = lines[i].replace(regex, function(match, operator, name) { 138 | switch(operator) { 139 | case "!": // ignore comments 140 | return match; 141 | case "=": // set new delimiters, rebuild the replace regexp 142 | that.set_delimiters(name); 143 | regex = new_regex(); 144 | return ""; 145 | case ">": // render partial 146 | return that.render_partial(name, context, partials); 147 | case "{": // the triple mustache is unescaped 148 | return that.find(name, context); 149 | default: // escape the value 150 | return that.escape(that.find(name, context)); 151 | } 152 | }, this); 153 | if(!in_recursion) { 154 | this.send(lines[i]); 155 | } 156 | } 157 | 158 | if(in_recursion) { 159 | return lines.join("\n"); 160 | } 161 | }, 162 | 163 | set_delimiters: function(delimiters) { 164 | var dels = delimiters.split(" "); 165 | this.otag = this.escape_regex(dels[0]); 166 | this.ctag = this.escape_regex(dels[1]); 167 | }, 168 | 169 | escape_regex: function(text) { 170 | // thank you Simon Willison 171 | if(!arguments.callee.sRE) { 172 | var specials = [ 173 | '/', '.', '*', '+', '?', '|', 174 | '(', ')', '[', ']', '{', '}', '\\' 175 | ]; 176 | arguments.callee.sRE = new RegExp( 177 | '(\\' + specials.join('|\\') + ')', 'g' 178 | ); 179 | } 180 | return text.replace(arguments.callee.sRE, '\\$1'); 181 | }, 182 | 183 | /* 184 | find `name` in current `context`. That is find me a value 185 | from the view object 186 | */ 187 | find: function(name, context) { 188 | name = this.trim(name); 189 | if(typeof context[name] === "function") { 190 | return context[name].apply(context); 191 | } 192 | if(context[name] !== undefined) { 193 | return context[name]; 194 | } 195 | // silently ignore unkown variables 196 | return ""; 197 | }, 198 | 199 | // Utility methods 200 | 201 | /* 202 | Does away with nasty characters 203 | */ 204 | escape: function(s) { 205 | return ((s == null) ? "" : s).toString().replace(/[&"<>\\]/g, function(s) { 206 | switch(s) { 207 | case "&": return "&"; 208 | case "\\": return "\\\\";; 209 | case '"': return '\"';; 210 | case "<": return "<"; 211 | case ">": return ">"; 212 | default: return s; 213 | } 214 | }); 215 | }, 216 | 217 | /* 218 | Merges all properties of object `b` into object `a`. 219 | `b.property` overwrites a.property` 220 | */ 221 | merge: function(a, b) { 222 | var _new = {}; 223 | for(var name in a) { 224 | if(a.hasOwnProperty(name)) { 225 | _new[name] = a[name]; 226 | } 227 | }; 228 | for(var name in b) { 229 | if(b.hasOwnProperty(name)) { 230 | _new[name] = b[name]; 231 | } 232 | }; 233 | return _new; 234 | }, 235 | 236 | // by @langalex, support for arrays of strings 237 | create_context: function(_context) { 238 | if(this.is_object(_context)) { 239 | return _context; 240 | } else if(this.pragmas["IMPLICIT-ITERATOR"]) { 241 | var iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator || "."; 242 | var ctx = {}; 243 | ctx[iterator] = _context 244 | return ctx; 245 | } 246 | }, 247 | 248 | is_object: function(a) { 249 | return a && typeof a == "object"; 250 | }, 251 | 252 | is_array: function(a) { 253 | return Object.prototype.toString.call(a) === '[object Array]'; 254 | }, 255 | 256 | /* 257 | Gets rid of leading and trailing whitespace 258 | */ 259 | trim: function(s) { 260 | return s.replace(/^\s*|\s*$/g, ""); 261 | }, 262 | 263 | /* 264 | Why, why, why? Because IE. Cry, cry cry. 265 | */ 266 | map: function(array, fn) { 267 | if (typeof array.map == "function") { 268 | return array.map(fn) 269 | } else { 270 | var r = []; 271 | var l = array.length; 272 | for(i=0;i' + 38 | '
' + 39 | '{{name}} @{{screen_name}}' + 40 | '
{{text}} {{created_at}}
' + 41 | '
'; 42 | 43 | var twitterPersonTemplate = 44 | '