Help
RSS
API
Feed
Maltego
Contact
Domain > devblog.bu.mp
×
More information on this domain is in
AlienVault OTX
Is this malicious?
Yes
No
Whois
Property
Value
Email
dcamacho@saipan.com
DNS Resolutions
Date
IP Address
2024-09-14
74.114.154.22
(
ClassC
)
Port 80
HTTP/1.1 301 Moved PermanentlyServer: nginxDate: Sat, 14 Sep 2024 19:13:51 GMTContent-Type: text/htmlContent-Length: 162Connection: keep-aliveLocation: https://devblog.bu.mp/ html>head>title>301 Moved Permanently/title>/head>body>center>h1>301 Moved Permanently/h1>/center>hr>center>nginx/center>/body>/html>
Port 443
HTTP/1.1 200 OKServer: nginxDate: Sat, 14 Sep 2024 19:13:52 GMTContent-Type: text/html; charsetUTF-8Content-Length: 153287Connection: keep-aliveVary: Accept-EncodingX-Rid: 9deb1e58bab363bc59fe39c4a74d13f7P3p: CPTumblrs privacy policy is available here: https://www.tumblr.com/policy/en/privacyX-Xss-Protection: 1; modeblockX-Content-Type-Options: nosniffStrict-Transport-Security: max-age15552001X-Tumblr-User: bumpdevblogX-Tumblr-Pixel-0: https://px.srvcs.tumblr.com/impixu?T1726341232&JeyJ0eXBlIjoidXJsIiwidXJsIjoiaHR0cDovL2RldmJsb2cuYnUubXAvIiwicmVxdHlwZSI6MCwicm91dGUiOiIvIn0&UBHDHOJFFGO&Kb386068c3ef5d0b18917cfe36411d57e11649e66cf205c19a4a06fd685679334--https://px.srvcs.tumblr.com/impixu?T1726341232&JeyJ0eXBlIjoicG9zdCIsInVybCI6Imh0dHA6Ly9kZXZibG9nLmJ1Lm1wLyIsInJlcXR5cGUiOjAsInJvdXRlIjoiLyIsInBvc3RzIjpbeyJwb3N0aWQiOiI1MzUyOTY0NDQzOSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9LHsicG9zdGlkIjoiNDA3ODYyMjE5MDIiLCJibG9nX-Tumblr-Pixel-1: aWQiOjg5OTA3OTczLCJzb3VyY2UiOjMzfSx7InBvc3RpZCI6IjQwNzg2MjIzMTQ2IiwiYmxvZ2lkIjo4OTkwNzk3Mywic291cmNlIjozM30seyJwb3N0aWQiOiI0MDc4NjIyMzk4NSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9LHsicG9zdGlkIjoiNDA3ODYyMjQ2MDciLCJibG9naWQiOjg5OTA3OTczLCJzb3VyY2UiOjMzfSx7InBvc3RpZCI6IjQwNzg2MjI1NDc3IiwiYmxvZ2lkIjo4OTkwNzk3Mywic291cmNlIjozM30seyJwb3N0aWQiOiI0MDc4NjIyNjAxMSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9LHsicG9zdGlkIjoiNDA3ODYyMjcwNzkiLCJibG9naWQiOjg5OTA3OTczLCJzb3VyY2UiOjMzfSx7InBvc3RpZCI6IjX-Tumblr-Pixel-2: QwNzg2MjI4NzkzIiwiYmxvZ2lkIjo4OTkwNzk3Mywic291cmNlIjozM30seyJwb3N0aWQiOiI0MDc4NjIyODA5MSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9XX0&UAEPOKBGMJE&Kea25025c5ec286ce23ac7162ac5684b32f1fd69d52a60ef37c4bcd8cd901949fX-Tumblr-Pixel: 3Link: https://64.media.tumblr.com/avatar_4f7f72a199bb_128.pnj>; reliconX-UA-Compatible: IEEdge,chrome1X-UA-Device: desktopVary: X-UA-Device, Accept, Accept-EncodingAccept-Ranges: bytesx-a8cblr: 1 !DOCTYPE html>script>var __pbpa true;/script>script>var translated_warning_string Warning: Never enter your Tumblr password unless \u201chttps://www.tumblr.com/login\u201d\x0ais the address in your web browser.\x0a\x0aYou should also see a green \u201cTumblr, Inc.\u201d identification in the address bar.\x0a\x0aSpammers and other bad guys use fake forms to steal passwords.\x0a\x0aTumblr will never ask you to log in from a user\u2019s blog.\x0a\x0aAre you absolutely sure you want to continue?;/script>script typetext/javascript languagejavascript srchttps://assets.tumblr.com/assets/scripts/pre_tumblelog.js?_vb9f848c06fcba7eaf305d4a7cb7a1b98>/script>html> head prefixog: http://ogp.me/ns# fb: http://ogp.me/ns/fb# blog: http://ogp.me/ns/blog#> title>Bump Dev Blog/title> meta charsetutf-8> meta namedescription content /> meta namecolor:Accent content#4EA3D0/> meta namefont:Body contentHelvetica Neue, Helvetica, Arial, sans-serif/> meta nameif:Two column posts content1/> !-- Appearance option --> meta nameif:Show bar on top content1/> meta nameif:Show blog title content1/> meta nameif:Show blog description content1/> meta nameif:Show profile photo content1/> meta nameif:Use endless scrolling content1/> meta nameif:Show right column content1/> meta nameif:Place timestamp in left column content1/> meta nameif:Use larger font for quotes content0/> meta nameif:Show image shadows content1/> meta nameif:Show tags content1/> meta nameif:Show post notes content1/> meta nameif:Show copyright in footer content1/> meta nametext:Disqus Shortname content /> meta nametext:Google Analytics ID content/> style>figure{margin:0}.tmblr-iframe{position:absolute}.tmblr-iframe.hide{display:none}.tmblr-iframe--amp-cta-button{visibility:hidden;position:fixed;bottom:10px;left:50%;transform:translateX(-50%);z-index:100}.tmblr-iframe--amp-cta-button.tmblr-iframe--loaded{visibility:visible;animation:iframe-app-cta-transition .2s ease-out}/style>link relstylesheet mediascreen hrefhttps://assets.tumblr.com/client/prod/standalone/blog-network-npf/index.build.css?_vf085dde138e244526309d4673db67b4c>link relshortcut icon hrefhttps://64.media.tumblr.com/avatar_4f7f72a199bb_128.pnj /> link relalternate typeapplication/rss+xml titleRSS hrefhttps://devblog.bu.mp/rss/> !-- HTML5 Shiv --> !--if lt IE 9> script srchttps://static.tumblr.com/hriofhd/Qj0m8pn7q/html5shiv.js>/script> !endif--> !-- Reset CSS --> link relstylesheet hrefhttps://static.tumblr.com/thpaaos/DIcklyl4z/reset.css typetext/css> !-- Theme CSS --> style typetext/css mediascreen> body { -webkit-font-smoothing: antialiased; font-size: 15px; font-family: Helvetica Neue, Helvetica, Arial, sans-serif; line-height: 24px; margin: 0; padding: 0; background-color: #2b2b2b; } *:active, *:focus { outline-width: 0px; } img { max-width: 100% } .post .top.media img { width: 100%; } a { text-decoration: none; color: #3370f0; } a img { border-width: 0px; } strong { font-weight: bold; } em { font-style: italic; } .group:after { visibility: hidden; display: block; content: ; clear: both; height: 0; } * html .group { zoom: 1; } /* IE6 */ *:first-child+html .group { zoom: 1; } /* IE7 */ iframe#tumblr_controls { top: 12px !important; } #color_bar { height: 12px; background: #3370f0; } #container { width: 950px; margin: 0 auto; padding: 60px 20px; } #header { height: 48px; margin: 0 0 60px 0; } #blog_info { width: 700px; margin: 0 60px 0 0; float: left; } #blog_info h1 { font-size: 36px; font-weight: bold; letter-spacing: -1px; line-height: 36px; margin: 8px 0 0 0; } #blog_info h1 a { color: #ebebeb; } #blog_info h1 a:hover { color: #000; } #blog_info h1 a:active { position: relative; top: 1px; } #blog_info p, #blog_info .cont { color: #646464; margin-top: 7px; } .cont { margin-bottom: 7px; } #blog_avatar { width: 188px; position: relative; float: right; } #blog_avatar a { width: 48px; height: 48px; -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, .21); box-shadow: 0px 1px 3px rgba(0, 0, 0, .21); position: absolute; top: 0; left: 0; display: block; } #blog_avatar img { width: 48px; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; } #blog_avatar a::before { content: ; width: 46px; height: 46px; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; border: 1px solid rgba(0,0,0,.1); position: absolute; top: 0px; left: 0px; z-index: 999; display: block; } #blog_avatar:hover a { width: 64px; height: 64px; top: -8px; left: -8px; } #blog_avatar:hover a img { width: 64px; } #blog_avatar:hover a::before { width: 62px; height: 62px; } #blog_avatar:active a { top: -7px; -webkit-box-shadow: 0px 0px 1px rgba(0, 0, 0, .21); box-shadow: 0px 0px 1px rgba(0, 0, 0, .21); } #posts { width: 700px; color: #b1b1b1; margin: 0 60px 0 0; float: left; } #posts .post { list-style-type: none; border-bottom: 1px solid #595959; margin: 0 0 45px 0; padding: 0 0 45px 0; } .top.audio * { width: 700px; height: 91px } .top.media { line-height: 0; -webkit-box-shadow: 0px 2px 7px 0px rgba(0, 0, 0, .27); box-shadow: 0px 2px 7px 0px rgba(0, 0, 0, .27); position: relative; display: inline-block; } .top.media.photoset { line-height: 0; -webkit-box-shadow: none; box-shadow: none; position: relative; display: inline-block; } .media img { -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; } .link_post .link { color: #7593d3; font-size: 21px; font-weight: bold; border: 1px solid rgba(51,112,240, 0.13); background: rgba(51,112,240, 0.13); -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; padding: 15px 53px 15px 20px; position: relative; display: block; } .link .arrow { width: 0; height: 0; border-top: 8px solid transparent; border-bottom: 8px solid transparent; border-left: 12px solid; color: 7593d3; position: absolute; top: 50%; right: 20px; margin-top: -8px; display: block; } .link_post .link:hover { border: 1px solid rgba(51,112,240, 0.2); background: rgba(51,112,240, 0.2); } .link_post .link:active { position: relative; top: 1px; } #posts .post .caption_and_post_info.after_top_part { border-top: 0; margin: 30px auto auto auto; padding-top: 0; } .post .caption { width: auto; float: none; } .post .caption { width: 513px; float: right; } .highlight { color: black; } code { font-weight: bold; } .content_source { margin-bottom: 20px; } .content_source img { margin: 0 0 0 4px !important; opacity: 0.7; vertical-align: middle; } .caption a, .description a { color: #3370f0; padding: 0 1px; } .caption a:hover, .description a:hover { background: rgba(51,112,240, 0.13); } .caption a:active, .description a:active { background: rgba(51,112,240, 0.2); } .caption h2 { font-size: 32px; line-height: 33px; margin: 0 0 18px 0; } .caption h2 a { color: #b6b6b6; font-weight: bold; letter-spacing: -1px; } .caption h2 a:hover { color: #3370f0; background: transparent; } .caption blockquote { border-left: 2px solid #69779b; padding: 1px 0 1px 20px; } .caption pre { background: #eee; font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Anonymous Pro, Courier New, monospace, serif; overflow: scroll; padding: 10px; border-radius: 3px; font-size: 13px; line-height: 19px; } .caption p, .caption ol, .caption ul, .caption pre, .caption h1, .caption h2, .post h3, .caption h4, .caption h5, .caption blockquote, .caption img, .caption embed, .caption object { margin: 0 0 20px 0; } .caption p:empty { display: none; } .caption iframe { display: block !important; } .post .caption ul, .post .caption ol { margin-left: 18px; } .caption .question { display: block; padding: 15px; font-size: 15px; } .caption .answer { margin-top: 20px; } .caption .asker { line-height: 24px; margin: 25px 20px 0 23px; } .caption .asker img { float: left; margin: 0 7px 0 0; } .caption .asker a { margin-left: 0; } .caption .quote { color: #d7d7d7; font-weight: bold; } .quote span { display: inline-block; } .quote.short_text { font-size: 50px; letter-spacing: -2px; line-height: 48px; margin: 0 0 18px 0; } .quote.short_text span { margin: 0 0 0 -22px; } .quote.medium_text { font-size: 36px; letter-spacing: -1px; line-height: 36px; margin: 0 0 20px 0; } .quote.medium_text span { margin: 0 0 0 -13px; } .quote.long_text, .quote.text { font-size: 24px; line-height: 27px; margin: 0 0 20px 0; } .quote.long_text span { margin: 0 0 0 -9px; } .quote.larger_text { font-size: 50px !important; letter-spacing: -2px !important; line-height: 48px !important; margin: 0 0 18px 0 !important; } .quote.larger_text span { margin: 0 0 0 -22px !important; } .quote_source { margin: 0 0 20px 0 !important; } .caption .conversation { margin-left: 0 !important; margin-bottom: 30px; list-style-type: none; } .conversation .chat_line { padding: 10px 16px; } .conversation .chat_line.user1 { background: #f5f5f5; } .conversation .chat_line.user2 { background: #fff; } .conversation .chat_line.user3 { background: #ddd; } .conversation .chat_line.user4 { background: #ccc; } .post .post_info { width: auto; font-size: 12px; font-family: Times New Roman, Times, serif; letter-spacing: 2px; text-transform: uppercase; list-style-type: none; -webkit-font-smoothing: subpixel-antialiased; margin: 1px 0 0 -3px; overflow: hidden; } .post_info li { line-height: 14px; margin-bottom: 10px; float: left; } .post_info li a { margin: 0 10px 0 0; padding: 0 2px 0 5px; } .post_info .timestamp { color: #868686; padding: 0 2px 0 5px; display: inline-block; } .post_info .timestamp:hover { background: rgba(0,0,0,.08); } .post_info .timestamp:active { background: rgba(0,0,0,.1); } .post_info .notecount { color: #4c4c4c; padding: 0 2px 0 5px; display: inline-block; } .post_info .notecount:hover { background: rgba(0,0,0,.08); } .post_info .notecount:active { background: rgba(0,0,0,.1); } /* Baselines */ .timestamp.has_caption { margin-top: 6px; } .timestamp.has_caption.with_title { margin-top: 18px } .tag { color: #3370f0; display: table; } .tag span { color: #4c4c4c; display: table-cell; } .tag:hover { background: rgba(51,112,240, 0.13); } .tag:hover span { color: #3370f0; } .tag:active { background: rgba(51,112,240, 0.2); } .post .post_info.floating { width: 157px; float: left; } .post .post_info.floating li { float: none; } .post_notes { clear: both; } ol.notes { color: #4C4C4C; font-size: 13px; text-shadow: 0px 1px 0px rgba(255,255,255,.7); text-align: left; list-style-type: none; border-top: solid 1px #E6E6E6; -webkit-font-smoothing: subpixel-antialiased !important; margin: 40px auto auto auto; } ol.notes li.note { border-bottom: solid 1px #E6E6E6; padding: 9px 0 10px 0; } ol.notes li.note img.avatar { width: 16px; height: 16px; border-radius: 3px; vertical-align: -4px; margin-right: 6px; } ol.notes a { color: #4C4C4C; text-decoration: underline; } ol.notes a:hover { color: #4C4C4C; } ol.notes li.note blockquote { border-color: #eee; padding: 4px 10px; margin: 10px 0px 0px 25px; } ol.notes li.note blockquote a { text-decoration: none; } ol.notes li.note:last-child { border-width: 0px; } #sidebar { width: 188px; color: #4c4c4c; font-size: 14px; margin: -8px 0 0 0; float: right; } #sidebar .description { line-height: 21px; border-bottom: 1px solid #E6E6E6; margin: 3px 0 20px 0; padding: 0 0 20px 0; } #sidebar .links { font-size: 12px; font-family: Times New Roman, Times, serif; letter-spacing: 2px; text-transform: uppercase; list-style-type: none; -webkit-font-smoothing: subpixel-antialiased; margin: 0 0 20px 0; line-height: 20px; } #sidebar .links a { color: #4c4c4c; } #sidebar .links a:hover { color: #3370f0; } .links .icon { width: 12px; height: 12px; background: #383838 url(https://static.tumblr.com/thpaaos/1xRm66voi/icons_sprite.png); margin: 0 8px 0 0; display: inline-block; } .links a:hover .icon { background-color: #3370f0; } .ask .icon { background-position: 0 0; margin-bottom: -2px; } .submit .icon { background-position: 0 -12px; margin-bottom: -1px; } .rss .icon { background-position: 0 -24px; } .archive .icon { background-position: 0 -36px; } .bubble { color: #6f6f6f; font-size: 13px; line-height: 20px; background: #f5f5f5; border: 1px solid #d5d5d5; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; padding: 8px 12px; position: relative; display: none; } #twitter_container .bubble:first-child { display: block; } .bubble .arrow { width: 0; height: 0; position: absolute; display: block; } .bubble .arrow.fill { border-left: 8px solid transparent; border-right: 8px solid transparent; border-top: 8px solid #f5f5f5; bottom: -8px; left: 25px; } .bubble .arrow.border { border-left: 10px solid transparent; border-right: 10px solid transparent; border-top: 10px solid #d5d5d5; bottom: -10px; left: 23px; } .bubble:hover { background: #f2f2f2; border-color: #CFCFCF; } .bubble:hover .arrow.fill { border-top-color: #F1F1F1; } .bubble:hover .arrow.border { border-top-color: #d5d5d5; } .twitter_username { max-width: 166px; color: #4c4c4c; font-size: 12px; font-family: Times New Roman, Times, serif; letter-spacing: 0.4em; text-transform: uppercase; text-overflow: ellipsis; -webkit-font-smoothing: subpixel-antialiased; margin: 11px 0 0 22px; overflow: hidden; display: inline-block; opacity: 1; } .twitter_username:hover { color: #3370f0; } #footer { width: 700px; color: #4C4C4C; font-size: 12px; font-family: Times New Roman, Times, serif; letter-spacing: 2px; text-transform: uppercase; -webkit-font-smoothing: subpixel-antialiased; } #footer .copyright { width: 50%; float: left; } #footer .pagination { width: 230px; text-align: right; float: right; position: relative; } .pagination .count { float: left; } .pagination .buttons { width: 113px; height: 30px; margin: -2px 0 0 30px; float: right; position: absolute; top: 0; right: 0; z-index: 10; } .pagination .buttons.disabled { z-index: 9; } .buttons a, .buttons li { width: 56px; height: 28px; line-height: 999px; text-align: center; border: 1px solid #C8C8C8; -webkit-box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, 1); box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, 1); background: #f1f1f1; /* Old browsers */ background: -moz-linear-gradient(top, #f1f1f1 0%, #e8e8e8 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f1f1f1), color-stop(100%,#e8e8e8)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, #f1f1f1 0%,#e8e8e8 100%); /* Chrome10+,Safari5.1+ */ background: -o-linear-gradient(top, #f1f1f1 0%,#e8e8e8 100%); /* Opera 11.10+ */ background: -ms-linear-gradient(top, #f1f1f1 0%,#e8e8e8 100%); /* IE10+ */ background: linear-gradient(top, #f1f1f1 0%,#e8e8e8 100%); /* W3C */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr#f1f1f1, endColorstr#e8e8e8,GradientType0 );/* IE6-9 */ list-style-type: none; overflow: hidden; position: relative; display: block; } .buttons.disabled li { background: #f5f5f5; } .buttons a:active { -webkit-box-shadow: none; box-shadow: none; background: #E6E6E6; } .buttons .arrow { width: 10px; height: 14px; position: absolute; top: 50%; display: block; background-image: url(https://static.tumblr.com/ogedyaw/xu1m8jxnf/arrow_sprite.png); } .buttons .left { -webkit-border-top-left-radius: 2px; -webkit-border-bottom-left-radius: 2px; -moz-border-radius-topleft: 2px; -moz-border-radius-bottomleft: 2px; border-top-left-radius: 2px; border-bottom-left-radius: 2px; position: absolute; left: 0; } .left .arrow { background-position: 0 15px; margin: -7px auto auto 20px; } .disabled .left .arrow { background-position: 0 0; } .buttons .right { border-left-width: 1px; -webkit-border-top-right-radius: 2px; -webkit-border-bottom-right-radius: 2px; -moz-border-radius-topright: 2px; -moz-border-radius-bottomright: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; position: absolute; right: 0; } .right .arrow { background-position: 10px -71px; margin: -7px auto auto 24px; } .disabled .right .arrow { background-position: 10px -56px; } /* Protection for parents that have floating children */ #header:after, #container:after, .caption_and_post_info:after, #footer:after .buttons:after { content: .; display: block; height: 0; clear: both; visibility: hidden; } /style> !-- Custom CSS --> style typetext/css mediascreen> /style> link relalternate hrefandroid-app://com.tumblr/tumblr/x-callback-url/blog?blogNamebumpdevblog />link relalternate hrefios-app://305343404/tumblr/x-callback-url/blog?blogNamebumpdevblog />script defer typeapplication/javascript idbilmur data-providertumblr.com data-serviceblognetwork data-customproperties{theme: } nonceSDQrPXOaNlHe4pJoT9LUoqVOHsE srchttps://s0.wp.com/wp-content/js/bilmur.min.js?m202437 >/script>script srchttps://assets.tumblr.com/assets/scripts/tumblelog_post_message_queue.js?_va8fadfa499d8cb7c3f8eefdf0b1adfdd>/script>link relstylesheet typetext/css hrefhttps://assets.tumblr.com/fonts/gibson/stylesheet.css?v3>!-- BEGIN TUMBLR FACEBOOK OPENGRAPH TAGS -->!-- If youd like to specify your own Open Graph tags, define the og:url and og:title tags in your themes HTML. -->!-- Read more: http://ogp.me/ -->meta propertyfb:app_id content48119224995 />meta propertyog:site_name contentTumblr />meta propertyog:title contentBump Dev Blog />meta propertyog:url contenthttps://devblog.bu.mp/?og1 />meta propertyog:description content />meta propertyog:type contentprofile />meta propertyog:image contenthttps://64.media.tumblr.com/avatar_4f7f72a199bb_128.pnj />meta propertyal:ios:url contenttumblr://x-callback-url/blog?blogNamebumpdevblog />meta propertyal:ios:app_name contentTumblr />meta propertyal:ios:app_store_id content305343404 />meta propertyal:android:url contenttumblr://x-callback-url/blog?blogNamebumpdevblog />meta propertyal:android:app_name contentTumblr />meta propertyal:android:package contentcom.tumblr />!-- END TUMBLR FACEBOOK OPENGRAPH TAGS -->!-- TWITTER TAGS -->meta charsetutf-8>meta nametwitter:site contenttumblr />meta nametwitter:card contentsummary />meta nametwitter:description content />meta nametwitter:title contentBump Dev Blog />meta nametwitter:app:name:iphone contentTumblr />meta nametwitter:app:name:ipad contentTumblr />meta nametwitter:app:name:googleplay contentTumblr />meta nametwitter:app:id:iphone content305343404 />meta nametwitter:app:id:ipad content305343404 />meta nametwitter:app:id:googleplay contentcom.tumblr />meta nametwitter:app:url:iphone contenttumblr://x-callback-url/blog?blogNamebumpdevblog&referrertwitter-cards />meta nametwitter:app:url:ipad contenttumblr://x-callback-url/blog?blogNamebumpdevblog&referrertwitter-cards />meta nametwitter:app:url:googleplay contenttumblr://x-callback-url/blog?blogNamebumpdevblog&referrertwitter-cards />!-- GOOGLE CAROUSEL -->script typeapplication/ld+json> {@type:ItemList,url:https:\/\/devblog.bu.mp,itemListElement:{@type:ListItem,position:1,url:https:\/\/devblog.bu.mp\/post\/53529644439\/introducing-bumptablecontroller},{@type:ListItem,position:2,url:https:\/\/devblog.bu.mp\/post\/40786221902\/flock-for-android-a-technical-breakdown},{@type:ListItem,position:3,url:https:\/\/devblog.bu.mp\/post\/40786223146\/my-summer-at-bump},{@type:ListItem,position:4,url:https:\/\/devblog.bu.mp\/post\/40786223985\/martin-gardner-had-a-timing-attack-for-your-m},{@type:ListItem,position:5,url:https:\/\/devblog.bu.mp\/post\/40786224607\/a-bump-up-27619},{@type:ListItem,position:6,url:https:\/\/devblog.bu.mp\/post\/40786225477\/a-bump-up},{@type:ListItem,position:7,url:https:\/\/devblog.bu.mp\/post\/40786226011\/from-mongodb-to-riak-7138},{@type:ListItem,position:8,url:https:\/\/devblog.bu.mp\/post\/40786227079\/git-for-dropbox-users-dont-be-afraid-11374},{@type:ListItem,position:9,url:https:\/\/devblog.bu.mp\/post\/40786228793\/easy-partial-screen-modals-on-ios},{@type:ListItem,position:10,url:https:\/\/devblog.bu.mp\/post\/40786228091\/who-said-android-apps-cant-look-good},@context:http:\/\/schema.org}/script>link relcanonical hrefhttps://devblog.bu.mp />/head> body> section idcolor_bar>/section> section idcontainer classgroup> header idheader> section idblog_info> h1>a href/>Bump Dev Blog/a>/h1> /section> /header> aside idsidebar> ul classlinks styledisplay:none;> /ul> ul classlinks> li>a hrefhttps://devblog.bu.mp/rss classrss>span classicon>/span>rss/a>/li> li>a href/archive classarchive>span classicon>/span>archive/a>/li> /ul> /aside> ul idposts> !-- START POSTS --> li classpost group > section classgroup caption_and_post_info > section classcaption group> h2>a hrefhttps://devblog.bu.mp/post/53529644439/introducing-bumptablecontroller>Introducing BumpTableController/a>/h2> div classcont group>p>em>This post was written by Indy from Bump’s mobile team./em>/p>p>Today we’re open sourcing a little library we’ve been using internally in Bump’s iOS projects for a while called a hrefhttps://github.com/bumptech/BumpTableController>BumpTableController/a>. BumpTableController provides a nice object-oriented and block-based API instead of the heavy indexPath delegate and dataSource methods for using UITableViews./p>p>As a quick example of what it looks like to show a simple list of strings:/p>ol>li>Hand a UITableView to a BumpTableController to manage:div classhighlight>pre>self.tableController BumpTableController alloc initWithTableView:_tableView; /pre>/div>BumpTableController is now the code>delegate/code> and code>dataSource/code> of the given UITableView./li>li>Create an code>NSArray/code>of BumpTableRow objects:div classhighlight>pre>NSMutableArray *rows NSMutableArray arrayWithCapacity:_myData count;br />for (NSString *str in _myData) {br /> BumpTableRow *row BumpTableRow rowWithKey:str height:44 reuseIdentifier:@Cell;br /> row.customizer ^(UITableViewCell *cell) {br /> cell.textLabel.text str;br /> };br /> rows addObject:row;br />} /pre>/div>The code>key/code> of each BumpTableRow must be unique. This is how code>transitionToModel:/code> below decides to to manage transitions./li>li>Tell BumpTableController to use this list of rows:div classhighlight>pre>_tableController transitionToModel:BumpTableModel modelWithRows:rows; /pre>/div>/li>/ol>p>If that looks appealing already you can get your hands on it on a hrefhttps://github.com/bumptech/BumpTableController>github/a> right way./p>h2>Why?/h2>p>Because constantly dealing with code>indexPath/code>s gets really annoying after a while. It’s simple enough to start working with your UITableView with the basic code>UITableViewDelegate/code> and code>UITableViewDataSource/code> callbacks. But when your model can change asynchronously, is used by two different UITableViews, or is not made of homogenous rows, things start to get tricky./p>p>At Bump we’ve had to build some fairly complex UITableViews before, from chat views to custom photo library views. And not just on iOS, we’ve had to do some fairly complex ListView implementations on Android as well. ListViews are the Android equivalent to UITableViews and all of its specification APIs are also index-based./p>p>While I was working on implementing some of the same things again on Android, I made a simple improvement to dealing with heterogeneous row types by specifying a list of Row objects to a somewhat generalized implementation of the ListView Adapter (or in iOS parlance and implementation of the Delegate and Datasource). I described it in blog post over at a hrefhttp://logc.at/2011/10/10/handling-listviews-with-multiple-row-types/>logc.at/a>./p>p>Last year when we were starting work on Flock, a hrefhttp://ianmacartney.com>Ian/a> decided to take things further. He wanted to to fully generalize the API to make it even simpler to use. He built the initial version of BumpTableController; since then the rest of the team at Bump has extended it make it work in more cases./p>h2>What it gives you/h2>p>I talked briefly that a list of Row objects is nicer to specify instead of managing all the indexing yourself. It’s a classic software engineering separation of concerns argument. Decision on which data to use when is abstracted away - you just need to declaratively specify the data in your Row objects./p>p>The other nicety is that a lot of the APIs are block-based. Blocks provide lightweight callbacks in C and Objective-C. It makes it really quick and easy to encapsulate related behavior for each Row without creating a new subclass for every different type of Row./p>p>Finally, using code>transitionToModel:/code> every time the model changes is that BumpTableController can figure out which rows to animate in/out/move. This means it unburdens you, the programmer, from figuring out the exact transitions yourself for most common cases./p>p>We hope you give BumpTableController a spin and let us know what you think. Go a hrefhttps://github.com/bumptech/BumpTableController>fork it on github/a>./p>/div> /section> ul class post_info floating > li>a hrefhttps://devblog.bu.mp/post/53529644439/introducing-bumptablecontroller class timestamp has_caption with_title >11 years ago/a>/li> li>a classnotecount hrefhttps://devblog.bu.mp/post/53529644439/introducing-bumptablecontroller#notes>5 notes/a>/li> /ul> /section> /li> li classpost group > section classgroup caption_and_post_info > section classcaption group> h2>a hrefhttps://devblog.bu.mp/post/40786221902/flock-for-android-a-technical-breakdown>Flock for Android: A Technical Breakdown/a>/h2> div classcont group>p>em stylemargin: 0px; padding: 0px; color: #424037; font-size: 12px; line-height: 21.600000381469727px;>This post was written by Indy and Sam, on Bump’s client team./em>/p>p>Flock for Android was just a twinkle in the eye of the Android users at Bump until early October. So when it was time for another hackathon, a few of us got together and threw together an early version of the app you see today. Since then we’ve been iterating and hardening Flock for Android. In this essay we will go through what it took to bring Flock to Android. br /> br />An early decision we made was to initially build the app with ICS in mind rather than older versions of Android. We are big fans of UI direction Android has taken since ICS and knew of a lot of great APIs that were introduced with ICS that would make Flock faster and better, and easier to build. Once we had the app working like we wanted, only then did we go back and see how we could make the app work on Gingerbread. This meant that we had to cut out some of the things that make the app super slick, but kept it functional./p>We decided not to go back further than Gingerbread. When we looked into it, we noticed market share for OSes pre Gingerbread are shrinking fast. We would open ourselves up for a whole host of bugs if we tried getting the app working with older phones, OSes, and missing APIs. Our small team simply didn’t have time to deal with that.p>/p>strong>Core/strong>When we started working on Flock for iOS we knew that we’d eventually build an Android version. And we followed the same pattern that we used in the Bump app to share code. We wrote a lot of C. In the Bump app we only had our core networking library in C (we have a custom protocol to talk to our servers), but in Flock we wanted to share code higher up the stack. We wrote all of the “core” logic in C. This is the layer that translates the packets we use to talk to the server into structures that our UI uses.p>/p>This C code has been running and been heavily debugged over the months that Flock for iOS has been out, and “all” we had to do was plop that C code into the Android app. Whenever you bring C code onto a new platform there is always a bit of work you need to do. But once that was good to go we had a fully functioning core of the app. All we had to do was consume the structures emitted from it.We use inproc zmq sockets to communicate between this core C layer and the Java UI layer. And the data is encoded using Protocol Buffers. We use exactly this structure for the iOS app, with the UI layer in Objective-C instead.p>/p>strong>UI/strong>While we were in the middle of implementing the iOS app, our design team produced an alternate design of the app, that focused much more on the display and exploration of photos. So when it came time to start implementing the UI, our hackathon team decided to build this design instead of simply porting the iOS UI. This design gives you a feel of exploring a large map of all your events and photos and fit better with the emphasis of larger screen sizes on Android. All the other information is only revealed as needed, giving a much more immersive and engaging experience.p>/p>Though we all loved this design there were a lot of challenges involved in implementing it. We only have a time to touch on a few for now.The first challenge was to get the basic layout framework working. Like with anything that has an unbounded list of objects we use the trusty ListView class in Android. Each row in this list is an album. Simple enough, we’ve done this before. However the design called for a horizontal swiping in each row to see the other photos in the album. This seemed like a use of the ViewPager class. Here we ran into our first hiccup.p>/p>Most places you see ViewPagers used, like the Play Store app and even the Bump app, ViewPagers page through full screen wide pages. There is one primary view that’s visible and then pages that it dynamically loads on either side of the page depending on which way people swipe. In Flock we wanted each item in our page to be a square with the ability to see a little bit of the page to the right. I thought it was time to start hacking android layouts, or if all else failed rebuild pagers with HorizontalScrollView (sort of how Pulse does it). But after some digging around I ran across a method on PagerAdapter called a hrefhttp://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#getPageWidth(int)>getPageWidth/a>. This was exactly what I was looking for, though it takes a percentage width instead of a an explicit size, but that’s easy enough do the math for.The second hiccup was how to shoehorn ViewPagers into ListViews. There are two problems with this. View pagers are designed to have vertical scrolling views in them (remember how we mentioned earlier that they are designed to be full screen views), not be contained in views that scroll vertically like ListViews. What this means is that the user must be very exact about scrolling vertically or else the ViewPager would just wiggle slightly left or right instead of letting us scroll vertically.p>/p>To solve this problem we basically took the approach described in a hrefhttp://stackoverflow.com/questions/7339558/android-listview-tolerance titleAndroid ListView Tolerance>this stackoverflow answer/a>. We intercepted touches and detected if there was more vertical distance in a scroll than a horizontal. If so then we gave precedence to the ListView over the ViewPager. This simple trick worked out beautifully.Once we had the basic view framework going we ran into our second major challenge. This was also related with trying to shoehorn ViewPagers into ListViews. The core of this problem is that ViewPagers are not really designed to do view recycling, which is essential to smooth vertical scrolling. Dian Hackborn, an Android framework engineer, had an exasperated reply when someone asked for help in doing this online:blockquote>p>span stylefont-family: Arial; color: #222222; vertical-align: baseline;>How exactly do you recycle the list view items correctly? This is… crazy. - a hrefhttps://groups.google.com/d/msg/android-developers/FO-NDXGUiGs/1rZMKf_zL-MJ>Diane Hackborn/a> /span>/p>/blockquote>p>Because of this we initially thought we were heading down the wrong path, but there were just too many things we got for free by using ViewPagers as ListView items that we decided to be a little crazy./p>p>strong>strong stylefont-family: Times; font-size: medium; font-weight: normal;>To get around the lack of view recycling we subclassed PagerAdapter and implemented recycling ourselves. The exposed methods are actually almost identical to a standard BaseAdapter (getView, getItemViewType etc.). We used a map of view type to queues of available pages to store recycled views. Whenever destroyItem is called for a particular view type, we add the corresponding view to the queue for that view type. Whenever instantiate item is called, before actually inflating a new view, we first check to see if we have a saved view in the corresponding queue in the map. While we got reasonable performance using this schema, it wasn’t sufficient. The order of the pages and the types of the pages in each row in Flock is determined by the number of photos in an event. Since most events have different numbers of photos, each row had a different sequence of view types. As the ViewPagers and PagerAdapters were reused during the user’s first few vertical swipes, the adapters were continually being asked to load new view types that other adapters had inflated, but the current one had not. Until every adapter had been asked to inflate a few of every view type we were inflating a lot of views, so there was a prolonged period of poor scrolling when users first opened the app. Since every adapter kept two or three views of each view type around, we were also using a fair amount of memory just keeping views around. The final step to help alleviate over inflating views and reduce memory usage was keep a single global map of view type to queue of views, rather than having each PagerAdapter have their own. Sharing views for pages across rows meant that we didn’t need to inflate as many views for each type and similarly didn’t need to keep as many views for each type around in memory./strong>/strong>/p>Along with some timely help from Romain Guy’s blog on a hrefhttp://www.curious-creature.org/2012/12/01/android-performance-case-study/ titleAndroid Performance by Romain Guy>android performance/a> and our own efforts at view recycling, we’ve been able to get good scrolling performance despite having complex row views displaying large images with very little padding. There is always room for improvement and we have a few ideas in mind to eliminate the last few scrolling hiccups for users with lots of events in a future version, but on the whole we’re pretty happy with the performance.strong>Background Location/strong>p>/p>One of the really interesting things Flock does is find out the friends you’re hanging out with to recommend exactly whom to share photos with. To achieve this we need to know where a user is without having them open the app. This is where the differences between iOS and Android API philosophies are really obvious.iOS gives apps a couple ways to do this as very high level APIs. One is to register for SLCs (Significant Location Updates) and a second is to register geo fences (region monitoring). Once you register for these you are at the system’s mercy to wake up your app when it thinks it’s right for you. Currently Flock for iOS relies primarily on SLCs, however SLCs didn’t behave the way we expected them to since they were designed for the opposite use case: moving a “significant” distance but not necessarily settling into a new place, which is what Flock needs. SLCs also come at a significant user perception cost because if your app registers for them, iOS will always show a solid location services arrow. strong stylefont-family: Times; font-size: medium; font-weight: normal;>Always/strong>strong stylefont-family: Times; font-size: medium; font-weight: normal;> (Even though iOS’s internal Traffic monitoring tools on your device use the same APIs but don’t show the arrow). This gives users the perception that the app always has the GPS on and is constantly consuming large amount of battery power, which is not really the case.Android on the other hand generally gives you access to much lower level data. You can register to listen to location updates on different location providers (GPS, Wi-Fi, Cell Tower Triangulation), and you can set up your app to be woken up at a certain time in the future and check these services yourself. This low level control gives developers a really easy way to shoot themselves in the foot by mistakenly asking for location too often (thus causing massive battery drain). But it also lets us be much more in control with our algorithm, giving us simpler ways to get to the information that we really want.All in all, it was a blast getting the Android version of Flock ready for prime time. We are super excited to have the app out there for general public to use, and drastically increase the number of people you can share photos with on Flock./strong>p> /p>/div> /section> ul class post_info floating > li>a hrefhttps://devblog.bu.mp/post/40786221902/flock-for-android-a-technical-breakdown class timestamp has_caption with_title >11 years ago/a>/li> li>a classnotecount hrefhttps://devblog.bu.mp/post/40786221902/flock-for-android-a-technical-breakdown#notes>2 notes/a>/li> /ul> /section> /li> li classpost group > section classgroup caption_and_post_info > section classcaption group> h2>a hrefhttps://devblog.bu.mp/post/40786223146/my-summer-at-bump>My Summer Internship at Bump/a>/h2> div classcont group>p classp1>em>This post was written by Andrew, a summer intern on Bump’s client team./em>/p>p classp1>Deciding where to intern is a big decision, or at least it was for me. Having never interned at a company before, I didn’t really know what to expect but knew what I wanted. I wanted to work on interesting problems, have freedom to create, and work with great people. With these considerations in mind, I chose to intern at Bump./p>p classp1>strong>Workbr />/strong>I came into Bump as an Android developer. Prior to Bump, I had some experience with the framework – I’d published an app. However, I still had much to learn (better realized after my internship)./p>p classp1>One of the most integral skills to software development is being able to reason at multiple levels of abstraction, and this is a skill my experience at Bump helped me hone. The Bump Android app is complex, but necessarily so. The app makes use of many of Android’s facilities, including that for embedded native code. The app must take into account the interaction between UI actions and network events, and does so nicely. When working on the Bump app, the professionalism with which it was created is noticeable. Looking back, I think my appreciation for the app’s structure is a testament to what I learned over the summer regarding modularity and reusable code design. Sure, anybody learns in school how to write generic code inside a few source files, but what about writing a component composed of many source files which must interact with a much larger machine?/p>p classp1>Another key skill I developed at Bump was working on a large codebase with other people. I am now infinitely more familiar with git than I was at the start of the summer, including managing projects with submodules. I think the day-to-day aspects of software development such as version control, setting up build environments, and team communication are under-emphasized in school and am glad for the experience I gained at Bump./p>p classp1>strong>Freedombr />/strong>An aspect of the work I did at Bump that I really enjoyed was the freedom I was given. The nature of the problems I solved at Bump was not “do this in O(whatever) runtime”. No, I was tasked with solving real problems the company faced – high level problems – and was given guidance in solving them. I found this freedom to be pervasive throughout my internship experience. For instance, I needed a lightweight way to log data from tests I was running and, even though I’m an Android developer, was able to play around with CherryPy to write a logging system. If I had questions, I was able to ask one of CherryPy’s lead developers – he works at Bump./p>p classp1>Freedom to do things the way you want is embedded into the culture of Bump. The Android developers use IntelliJ because they like its memory usage and code completion better than Eclipse. However, if you want to use Eclipse, you can. Want to run Eclipse inside an Ubuntu VM? Go for it. How about forgoing the whole thing and just using vim and a terminal? Your choice./p>p classp1>The openness and willingness to try new things as a company is one of my favorite aspects of Bump./p>p classp1>strong>Lifebr />/strong>As I’m still in college (Stanford ‘14), life at work was a major factor in deciding where to intern – Bump does not disappoint. I think it’s pretty cool when you can play Berlin-style ping pong and sing karaoke at work. The people at Bump are great and fun to be around. While people take their work seriously, they don’t take themselves too seriously./p>p classp2>Speaking of ‘seriously’, you may be wondering what the hours are like. Most people don’t show up until around 10 which was great for me. People generally leave around 7 but there is no set time. Personally, I’d usually leave around 8, but that was voluntary – I just figured that experiences like these don’t come too often and wanted to make the most of it. However, the culture is flexible – a few days I had to leave around 5:30 and would, no questions asked. The emphasis at Bump is on the actual work you do, not the time. That said, if you don’t want to em>work/em>, don’t work at Bump. At Bump, you will work but you’ll have fun doing it./p>p classp3>strong>Foodbr />/strong>Food was great – would eat again./p>p classp2>At Bump, you’re surrounded by food. The company has a snack bar and refrigerator of drinks which get replenished weekly. You can have as many snacks/drinks as you want whenever you want. The company provides two catered lunches per week. Lunches range from Indian food to Pakistani to Jamaican. There were times when I would have preferred a burger or pizza, but I took the opportunity as a great time to expand my palate. Most importantly, when Bump gets food catered, there is a lot of it. There are usually leftovers which is awesome for the days following catered lunch days. Bump’s also really close to Castro Street which has more food than you can eat in a summer (I tried) and there is almost always a group willing to go grab something. For the company I’m not sure how the unlimited food model works – my productivity definitely went down during the post-lunch food coma, but for me it was great./p>p classp2>strong>Should I Work There?br />/strong>If you’re reading this, you’re probably asking yourself that question (otherwise, you have a lot of free time and/or enjoy reading intern blogs).While we both know there’s no definitive answer, Bump has my recommendation. I had a great time interning at Bump and the rest of the interns my year seemed to have very positive experiences as well. Ultimately, you’re going to have to go with your gut. I did, and it was one of the best decisions I’ve made./p>/div> /section> ul class post_info floating > li>a hrefhttps://devblog.bu.mp/post/40786223146/my-summer-at-bump class timestamp has_caption with_title >11 years ago/a>/li> /ul> /section> /li> li classpost group > section classgroup caption_and_post_info > section classcaption group> h2>a hrefhttps://devblog.bu.mp/post/40786223985/martin-gardner-had-a-timing-attack-for-your-m>Martin Gardner had a timing attack for your mind (1956)./a>/h2> div classcont group>p classp1>em>This post was written by Seth, Bump’s resident iOS Magician./em>/p>p stylemargin-top: 0px !important; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding: 0px; line-height: 1.4em;>a hrefhttp://en.wikipedia.org/wiki/Martin_gardner>Martin Gardner/a> was a math and science writer, who also was a magician. In one of his books, he teaches a magic trick that bears some similarities to a more recent technique for stealing passwords from systems that are using an insecure HMAC checking algorithm./p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>So, let’s bring together a hrefhttp://en.wikipedia.org/wiki/HMAC#Security>HMAC security/a>, mathematician Martin Gardner, magic, and a timing attack on your brain (and throw in app virality at the end). Do I have your attention yet, Hacker News?/p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>What is a Timing Attack?/p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>A a hrefhttp://en.wikipedia.org/wiki/Timing_attack>timing attack/a> uses information leaked by a computer system based on the amount of time it takes for something to happen. For example, let’s imagine I want to compare two strings for equality (say to check a password (which you would never want to do!)): “Hello World!” and “¡Hola Mundo!”. A simple algorithm could compare letter by letter, and return false as soon as one character doesn’t match. In this case, no characters match, so it would return pretty fast. If I were comparing “Hello World!” to “Hello Wormy!”, the algorithm would have to compare 10 characters, and so would take 10 times as long (factoring out the parts of the function that are run on every call). Using this timing information (on a sufficiently slow machine), you could uncover the password, one letter a time by simply iterating over each possible letter until the algorithm took a little longer, and then proceed to do the next character in the password./p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>This overly-simplified timing attack is similar to a real potential attack to using HMACs./p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>Magic Trick?/p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>Martin Gardner described a timing attack on your mind in his book ’a hrefhttps://t.umblr.com/redirect?zhttp%3A%2F%2Fwww.amazon.com%2FMathematics-Magic-Mystery-Dover-Recreational%2Fdp%2F0486203352&tY2YzNzI4YmU4NGIxZGUxZjI2YTNjMzBkMGVhMTlkM2EzZjUwZWY3ZixvZnlTdUxWSQ%3D%3D&bt%3AXvckHOaPjER_-EG_bgFjFw&phttps%3A%2F%2Fdevblog.bu.mp%2Fpost%2F40786223985%2Fmartin-gardner-had-a-timing-attack-for-your-m&m1&ts1726341232>Mathematics, Magic and Mystery/a>’ in 1956. It is a magic trick called “Divining a Number” which involves discovering the number that your spectator is merely thinking of./p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>You may have heard of simpler magic tricks where you ask someone to think of a number, perform some math, and then can tell them the number they end up on. This magic trick is different. You tell them the number they originally thought of, and they never tell you any of the results of their mental math./p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>You ask them to think of a number, have them do some mental math, without saying anything, and then you know which number they thought of./p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>You discover the thought-of-number by using a timing-attack like process on their mental math. A simple example:/p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>Think a number: 8 or 9 (a simple choice of two numbers)./p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>Now, divide that number by 2./p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>To be fair, you are probably better at mental math than the average person by virtue of the fact that you are reading this article, but it is signifcantly easier for most people to divide an even number by 2 than an odd number. So, by watching your face as you did this mental math, I could tell you which number you were thinking of. If you were really fast, you were thinking of 8, slow means 9./p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>If you add a few more mental math timings, you can expand the original range of choices from 2, up to 10. Martin Gardner describes the whole (rather complicated) procedure in his book./p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>Martin Gardner didn’t invent the technique (he heard about it from Edmund Balducci), and it is based on several tricks found in “The Magician’s Own Book” published in 1862! Timing attacks go way back!/p>p stylemargin: 15px 0px; padding: 0px; line-height: 1.4em;>App Virality?/p>p stylemargin-top: 15px; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 0px; line-height: 1.4em;>I’m a magician, and also a software engineer at Bump. Part of my job is to explore using the theory behind magic tricks (including mental timing attacks) to improve our app’s virality. If you want to learn how, or if you want instructions for the full magic trick, e-mail a relnoreferrer stylemargin: 0px; padding: 0px; line-height: 1.4em; color: #4183c4;>/a>a hrefmailto:seth@bu.mp>seth@bu.mp/a> !/p>/div> /section> ul class post_info floating > li>a hrefhttps://devblog.bu.mp/post/40786223985/martin-gardner-had-a-timing-attack-for-your-m class timestamp has_caption with_title >12 years ago/a>/li> /ul> /section> /li> li classpost group > section classgroup caption_and_post_info > section classcaption group> h2>a hrefhttps://devblog.bu.mp/post/40786224607/a-bump-up-27619>A Bump Up - Reflections on Startup Life/a>/h2> div classcont group>p>em>This post was written by Greg, a summer intern on Bump’s server team./em>/p>p>Internships are such a fantastic opportunity to explore different companies, work cultures, and cities that I sometimes wish I could forever do internships, trying and learning a little bit of everything, everywhere. Alas, there are only a a hrefhttp://xkcd.com/1070/>couple/a> summers as an undergraduate to be an intern, so I wanted to pack in as much learning and fun as possible./p>p>After a solid first internship with Amazon’s Kindle division in Seattle last summer, I wanted to explore the opposite end of the tech company spectrum for my second internship, so I could make more well-informed career decisions after graduation. Bump caught my attention very early in the internship search. It was a small company working with open source software developing a truly one-of-a-kind product that makes life easier for tens of millions of users. A userbase of that size provides a great opportunity for machine learning, exposure to real-world architectural and scaling challenges, and a guarantee that my work would have a big impact./p>p>My interest in Bump only grew during the interview process. Bump’s programming challenge and interview questions were practical and engaging, which was a refreshing change from the slew of linked-list manipulation, string-integer conversion, and fizzbuzz questions I had been answering in other interviews at the time. Before I knew it, I was on my way to California for the first time, and to the heart of Silicon Valley at that!/p>p>The first week was a bit overwhelming; it took a while to get used to the unstructured start-up environment and to learn who to ask for help. Once past these initial roadbumps however, I’ve gotten the chance to explore a variety of cool projects with the server and data teams and am still learning a ton everyday. In reflecting on my time here, I’m very grateful for a few qualities of this internship that exceed my experiences from last summer, especially these three things:/p>ul>li>Important work. While the project I worked on at Amazon was a neat idea that would have improved the Kindle experience for tens of thousands of people, it was more of a nice-to-have feature than anything else. I found out later that, unfortunately, it was shelved after I left because there were more valuable things to work on. This is not an issue with Bump. Because the company is so small and the userbase is so large, everyone’s work is critical (even interns’) and there is no shortage of important work to take on. The effort of a single person here can have a very visible impact on the product, and consequently, on the lives of millions of people. It’s exciting that my work on debugging tools and analytics will directly improve the service and experience for all of Bump’s users./li>/ul>ul>li>Speed. I feel like I’ve accomplished more at Bump already than I did all of last summer. The pace throughout the company is very fast, and it works because everyone has a “get things done” mindset. There aren’t any obligations to distant departments or chains of managers to go through, and everyone in the company is within a 10 second walk of my desk, making it easy to ask questions and clear obstacles. The speed is a great motivator, as well, because progress is evident and exciting as we rapidly approach our goals. /li>/ul>ul>li>Fun culture. Amazon had very cool weekly tech talks by senior engineers and also brought in various performers and artists (I even got to meet my favorite author, GRRM!). Aside from these events though, the majority of my work culture experience at Amazon was dominated by the company policy of frugality. I have a lot of respect for that policy and all the work Amazon puts into lowering prices and improving service for consumers, but I feel that having a much brighter, more open office with a few games and snacks has greatly improved my mood while at the office. I appreciate that – when I get stuck on a problem – I can get up, be active, and talk through the problem with a coworker over a game of ping pong. By the time I return to my desk, I can see the solution to the problem or I will at least have a new perspective or approach for tackling it. Little things like this, plus organized company events such as trivia night and ultimate frisbee matches against other startups have made the entire internship experience more enjoyable./li>/ul>p> /p>p>I’ve found that qualities such as these are very important to me not only today as an intern, but also as an eventual career-seeker. Bump has been successful at not only attracting smart, like-minded people, but also cultivating a positive and playful work culture where everyone motivates each other to build the best product they can imagine. Needless to say, I’m excited to be a part of this team and to continue building and learning here for the rest of the summer!/p>p> /p>p> /p>/div> /section> ul class post_info floating > li>a hrefhttps://devblog.bu.mp/post/40786224607/a-bump-up-27619 class timestamp has_caption with_title >12 years ago/a>/li> /ul> /section> /li> li classpost group > section classgroup caption_and_post_info > section classcaption group> h2>a hrefhttps://devblog.bu.mp/post/40786225477/a-bump-up>A Bump Up/a>/h2> div classcont group>p classp1>em>This post was written by Greg, a summer intern on Bump’s server team./em>/p>p>strong stylefont-family: Times; font-size: medium; font-weight: normal;>Internships are such a fantastic opportunity to explore different companies, work cultures, and cities that I sometimes wish I could forever do internships, trying and learning a little bit of everything, everywhere. Alas, there are only a a hrefhttp://xkcd.com/1070/ target_blank>couple/a> summers as an undergraduate to be an intern, so I wanted to pack in as much learning and fun as possible.br /> br />After a solid first internship with Amazon’s Kindle division in Seattle last summer, I wanted to explore the opposite end of the tech company spectrum for my second internship, so I could make more well-informed career decisions after graduation. Bump caught my attention very early in the internship search. It was a small company working with open source software developing a truly one-of-a-kind product that makes life easier for tens of millions of users. A userbase of that size provides a great opportunity for machine learning, exposure to real-world architectural and scaling challenges, and a guarantee that my work would have a big impact.My interest in Bump only grew during the interview process. Bump’s programming challenge and interview questions were practical and engaging, which was a refreshing change from the slew of linked-list manipulation, string-integer conversion, and fizzbuzz questions I had been answering in other interviews at the time. Before I knew it, I was on my way to California for the first time, and to the heart of Silicon Valley at that!/strong>/p>The first week was a bit overwhelming; it took a while to get used to the unstructured start-up environment and to learn who to ask for help. Once past these initial roadbumps however, I’ve gotten the chance to explore a variety of cool projects with the server and data teams and am still learning a ton everyday. In reflecting on my time here, I’m very grateful for a few qualities of this internship that exceed my experiences from last summer, especially these three things:ul>li>strong stylefont-family: Times; font-size: medium; font-weight: normal;>strong stylefont-weight: normal;>Important work. While the project I worked on at Amazon was a neat idea that would have improved the Kindle experience for tens of thousands of people, it was more of a nice-to-have feature than anything else. I found out later that, unfortunately, it was shelved after I left because there were more valuable things to work on. This is not an issue with Bump. Because the company is so small and the userbase is so large, everyone’s work is critical (even interns’) and there is no shortage of important work to take on. The effort of a single person here can have a very visible impact on the product, and consequently, on the lives of millions of people. It’s exciting that my work on debugging tools and analytics will directly improve the service and experience for all of Bump’s users.br /> /strong>/strong>/li>li>strong stylefont-family: Times; font-size: medium; font-weight: normal;>strong stylefont-weight: normal;>Speed. I feel like I’ve accomplished more at Bump already than I did all of last summer. The pace throughout the company is very fast, and it works because everyone has a “get things done” mindset. There aren’t any obligations to distant departments or chains of managers to go through, and everyone in the company is within a 10 second walk of my desk, making it easy to ask questions and clear obstacles. The speed is a great motivator, as well, because progress is evident and exciting as we rapidly approach our goals. br /> /strong>/strong>/li>li>strong stylefont-family: Times; font-size: medium; font-weight: normal;>strong stylefont-weight: normal;>Fun culture. Amazon had very cool weekly tech talks by senior engineers and also brought in various performers and artists (I even got to meet my favorite author, GRRM!). Aside from these events though, the majority of my work culture experience at Amazon was dominated by the company policy of frugality. I have a lot of respect for that policy and all the work Amazon puts into lowering prices and improving service for consumers, but I feel that having a much brighter, more open office with a few games and snacks has greatly improved my mood while at the office. I appreciate that – when I get stuck on a problem – I can get up, be active, and talk through the problem with a coworker over a game of ping pong. By the time I return to my desk, I can see the solution to the problem or I will at least have a new perspective or approach for tackling it. Little things like this, plus organized company events such as trivia night and ultimate frisbee matches against other startups have made the entire internship experience more enjoyable./strong>/strong>/li>/ul>p>strong stylefont-family: Times; font-size: medium; font-weight: normal;>br />I’ve found that qualities such as these are very important to me not only today as an intern, but also as an eventual career-seeker. Bump has been successful at not only attracting smart, like-minded people, but also cultivating a positive and playful work culture where everyone motivates each other to build the best product they can imagine. Needless to say, I’m excited to be a part of this team and to continue building and learning here for the rest of the summer!br />/strong>/p>/div> /section> ul class post_info floating > li>a hrefhttps://devblog.bu.mp/post/40786225477/a-bump-up class timestamp has_caption with_title >12 years ago/a>/li> /ul> /section> /li> li classpost group > section classgroup caption_and_post_info > section classcaption group> h2>a hrefhttps://devblog.bu.mp/post/40786226011/from-mongodb-to-riak-7138>From MongoDB to Riak/a>/h2> div classcont group>p>em>This post is written by Tim on Bump’s server team/em>/p>p>At Bump Technologies, we recently completed a significant database migration from MongoDB to Riak. Almost all of our users’ data – the lists of people they’ve bumped, communications sent and received, handset information, social network OAuth tokens, etc. – had been stored in MongoDB, but if you open the app today all of these interactions will be backed by Riak./p>div stylepadding-right: 1px;>div stylepadding-right: 1px;>span styleline-height: 17px;>A few months ago we had migrated our datastore containing individual communication contents from MongoDB to Riak, so these databases and general migration techniques were not entirely foreign to us, but any time you have to move data while keeping the system online, it’s a unique and complicated challenge./span>/div>p>/p>div stylepadding-right: 1px;>span stylefont-family: Arial, sans-serif;>strong>Development obstacles/strong>/span>/div>div stylepadding-right: 1px;>span styleline-height: 17px;>The largest development hurdle was dealing with the structured key-document nature of MongoDB vs. the key-value nature of Riak combined with the latter’s eventual consistency. At Bump we use Google’s Protocol Buffers extensively, for serialization to Riak and message passing between the Bump client and the server, and between server application nodes. In addition to being an efficient encoding, it also enforces types and provides for backwards- and forwards-compatibility. MongoDB’s key-document knowledge and consistency model allow it to support, e.g., atomic list appends, which we would use to add to a user’s list of communications when they sent one./span>/div>p>/p>div stylepadding-right: 1px;>span styleline-height: 17px;>Riak does not have any internal knowledge of how the Protocol Buffers we are storing are formed, and cannot guarantee the same kinds of consistency. Instead, we have to grab the value for the key, update it ourselves, and put it back in. That’s easy (if a bit more verbose than what MongoDB does), but the difficulty comes when dealing with concurrency. One of our app nodes could get a user’s record, then append the communication the user just sent, and save it to Riak. The database, being eventually consistent, cannot guarantee that when another app node gets the record it contains the communication just written. If the second app node then makes changes and overwrites the key with their new value, data will be lost. /span>/div>div stylepadding-right: 1px;>span styleline-height: 17px;>Riak is pretty smart, though, and will save both of these values. Upon the next get, it will return the two valid values (if, that is, the node has received both!), leaving it up to the app to deal with the multiple truths. With appropriate logic (set unions, timestamps, etc) it is easy to resolve these conflicts, but dealing with this everywhere a database fetch happens is cumbersome. Instead, we’ve written a thousand-line Haskell program that acts as an interface between the app nodes and the database, which exclusively deals with conflict resolution and sibling merges. Every Riak interaction is done through this tool that we’ve dubbed /magicd/, which guarantees the app nodes always see a consistent truth. This obviates the largest pain point of eventually consistent databases./span>/div>p>/p>div stylepadding-right: 1px;>span styleline-height: 17px;>After evaluating our migration options, we decided to approach it on-the-fly. The other significantly considered technique was migrating in parallel; everywhere Mongo was written we would append a write to Riak, and everywhere a Mongo read was done it would be prefixed with a read from Riak, falling back to Mongo if the data had not been migrated. This two-database parallel approach was appealing in that if something horrible happened during the transition, we could revert to pre-migration behavior (i.e., drop all of the Riak code), and the data would be consistent and up-to-date in Mongo as before./span>/div>div stylepadding-right: 1px;>span styleline-height: 17px;>The difficulty with this approach was that, despite almost all of our database interactions being encapsulated in a class, there were a few scattered circumstances in which the database was written to outside of the class. Those instances, of course, were only a grep away, but the significant amount of code / logic duplication for those special-cased interactions was a deterrent./span>/div>p>/p>div stylepadding-right: 1px;>span styleline-height: 17px;>Instead, we decided to migrate all of the users’ data on the fly on login. With the first packet received from the handset, we block all other communication until the user has had all of its data written to Riak. It then proceeds as normal, with all other database interactions in the server codebase having been converted to use Riak exclusively. The upside of this compared to the previous parallel approach was simplicity; s/mongo/riak/g and call it a day, instead of handling two data code paths. The downside was that a rollback to Mongo in case of significant errors could lose data, either temporarily if the new data written to Riak was recoverable, or permanently if not. Despite the downside, with extensive testing we were able to ferret out any bugs that would result in data loss, and suffered none on roll out./span>/div>p>/p>div stylepadding-right: 1px;>span stylefont-family: Arial, sans-serif;>strong>span styletext-decoration: underline;>Post-deployment obstacles/span>/strong>/span>/div>div stylepadding-right: 1px;>span styleline-height: 17px;>Significant testing before rollout could nevertheless not definitively show us all of the bugs that existed. Specifically, we encountered a few errors that were only made evident with production data and traffic./span>/div>p>/p>div stylepadding-right: 1px;>span styleline-height: 17px;>The first issue we saw after deployment was one of our Redis instances complaining about hitting its maximum connection limit. We use Redis throughout Bump’s backend, performing a number of duties including queueing, session caching, and even geolocation mapping. Using it as a networked locking mechanism for migration purposes was a natural progression. The code we wrote, now included as part of the diesel async framework we use, did not appropriately close the connection in some circumstances. With that fixed, the Redis connections dropped to a normal and expected number./span>/div>div stylepadding-right: 1px;>span styleline-height: 17px;>The second class of issues we encountered was a product of the relaxed schema of Mongo and the strict serialization of Protocol Buffers. There’s no way to enforce types for values within a Mongo document; an integer may be stored as an integer, or a string representation of the same, for example. Depending on the leniency of application code, this fast-and-loose typing may be acceptable./span>/div>p>/p>div stylepadding-right: 1px;>span styleline-height: 17px;>Protocol Buffers are much more strict about the types they accept. If one tries to assign a string to a value defined as an int32 in the protobuf definition file, it will refuse to be serialized. This manifested itself in our code when we tried to serialize the Apple Push Notification Service token; in some circumstances, it contained characters that broke when being parsed as a Protocol Buffers string; changing that type to bytes fixed the issue. This modification of the definition file preserved backwards-compatability because strings and bytes are stored in serialized format in the same way./span>/div>div stylepadding-right: 1px;>span styleline-height: 17px;>Unlike JSON/BSON where there is no defined schema and one can throw in any values they desire, Protocol Buffers can specify required fields. A object that must have a user_id, for example, cannot be serialized without that field set. This does wonders when doing client-server communication or serialization to a database, for contracts can be made and consistently followed. During the migration, there were a number of fields that should have been set in Mongo but were not. Luckily, they were comparatively menial values – last seen Bump version number and locale for a user, for example – but their lack of existence in Mongo caused their migration pipeline to break. Setting empty locales and 0.0.0 version numbers was deemed a satisfactory resolution considering the importance of the data./span>/div>p>/p>div stylepadding-right: 1px;>span styleline-height: 17px;>With the above issues solved, our Python processes stopped spewing hundreds of exceptions, and things on the app node side seemed to be cooling down. At this point, we turned our attention to Riak load; we started to see latencies rise to concerning levels. In addition, we started receiving user reports that database-heavy operations were acting slower than they had prior. Further investigation showed that our magicd processes were pegging the CPU, so as a temporary fix, we increased the number of threads the process would spawn. Benchmarking revealed that magicd was serializing and deserializing every protobuf that went through it; this was only necessary when siblings existed and needed to be resolved, so fixing it so deserialization only occurred when required reduced load to a more manageable level./span>/div>div stylepadding-right: 1px;>span styleline-height: 17px;>While this helped magicd CPU requirements, we were still seeing elevated Riak latencies. Investigating the logs showed some particularly abnormal behavior on one node in particular; upon sshing in and poking around, it became apparent that one of its disks had failed. Shutting down the riak daemon on that node caused to latencies fall back to normal levels. After getting the disk issues resolved, we were able to bring the node back online. Thankfully due to Riak’s destributed nature, a missing node in the cluster was not a problem; we still saw great performance./span>/div>div stylepadding-right: 1px;>strong>span styletext-decoration: underline;>Post-Mortem/span>/strong>/div>p>/p>div stylepadding-right: 1px;>span styleline-height: 17px;>We decided to move to Riak because it offers better operational qualities than MongoDB. Despite the migration hiccups, we’re pleased with the process and the result. Now we no longer care if one of the nodes kernel panics in the middle of the night; as has happened a few times already. Nagios will email us instead of page us, and over coffee the next morning we’ll fire up IPMI, reboot the machine, and Riak will read-repair as necessary. No longer will we have to do any master-slave song and dance, nor will we fret about performance, capacity, or scalability; if we need more, we’ll just add nodes to the cluster. /span>/div>div stylepadding-right: 1px;>span styleline-height: 17px;>If you have any questions about our experience, or want to work with us on this joyful stack (we’re hiring!) – shoot me an email: a hrefmailto:timdoug@bu.mp>timdoug@bu.mp/a>./span>/div>/div>p> /p>/div> /section> ul class post_info floating > li>a hrefhttps://devblog.bu.mp/post/40786226011/from-mongodb-to-riak-7138 class timestamp has_caption with_title >12 years ago/a>/li> /ul> /section> /li> li classpost group > section classgroup caption_and_post_info > section classcaption group> h2>a hrefhttps://devblog.bu.mp/post/40786227079/git-for-dropbox-users-dont-be-afraid-11374>git for dropbox users: Don’t be afraid!/a>/h2> div classcont group>h1>git is awesome/h1>p>We use git at Bump for all sorts of things. Recently, we’ve started converting our designers and product managers. You can think about git like Dropbox: it takes files on your computer, puts them in the cloud, and lets other people work on them too. But it has some pretty rocking advantages:/p>h3>Collaboration/h3>p>Like Dropbox, git lets multiple people work on the same files at the same time. This is great when many people are working on a document together, or a group of people are creating assets for a website. Everyone can be contributing to the same folder and files, without fear of overwriting eachother’s work, something Dropbox can scew up./p>h3>Time Machine/h3>p>Even if you don’t have a team of people, git has some awesome-sauce. It can act like a time machine, allowing you go and see what you did last week, or even last year, help you recover files you deleted, and keep track of progress over time. It has powerful tools to let you see what you’ve changed over time./p>h3>And More/h3>p>git is also great for backing things up, so you don’t lose them. It can let you learn about how you work: when do you do your best work? How often do you change everything? There are tools to show you visual differences between versions of images, and all sorts of things./p>h1>but/h1>p>git is awesome… but conceptually it’s a leap from most people’s mental models of what a file is./p>p>There are so many wonderful reasons for non-programmers to use git when working with other people (especially programmers) and I’d like to convince you that there are even more awesome rewards down the way of git, but I won’t do that today./p>p>My goal today:/p>blockquote classposterous_short_quote>p>Provide an analogy to Dropbox to help designers and product managers understand the mental model of how git works./p>/blockquote>p>It might help you to think about git like Dropbox to start. It’s like Dropbox but with a whole lot more steps. Have faith (for the moment) that the more steps are worth it, and I’ll talk you through the differences./p>p>First, a quick overview of how Dropbox works: many people can be working on the same file on their own computers, and magically they all get each other’s changes. Behind the scenes Dropbox is doing all sorts of things to make this work. With git, you end up helping do some of the behind the scenes work, and git thanks you./p>h1>As easy as 4… 5… 6!/h1>p>Here is a more explicit model of how Dropbox works./p>ol>li>You install Dropbox./li>li>Someone shares a folder with you./li>li>Your computer downloads the contents of that folder from the “Cloud”/li>li>You make some changes to a file in the folder and save it./li>li>Your changes get sent up to the Dropbox “Cloud” immediately/li>li>Everyone else gets your changes downloaded to their computers immediately./li>/ol>p>Yay. This is just like git! Only git lacks some of the “immediately” magic. Steps 4, 5, and 6 don’t happen automatically: you have to tell git when you want it to do each step. Let me break it down for you./p>h3>4) Saving… are you sure?/h3>p>The first difference is that git doesn’t assume that you want to send every saved change to the cloud. It makes you be explicit about what you want to send to the cloud./p>blockquote classposterous_medium_quote>p>Whereas Dropbox automatically uploads everything when you save it, git adds a new step: commitment. After you save a file, you must tell git that you are “committed” to this change./p>/blockquote>p>To do this, you do what is called “staging.” This is really just telling git which changes you were sure about. This way, git doesn’t waste other people’s time if you make a draft you don’t like./p>h3>5) Uploading/h3>p>Second difference: Dropbox uploads your files immediately. (It tries to anyway). git isn’t quite as eager to get things into the cloud./p>blockquote classposterous_medium_quote>p>In git, uploading to the cloud is called “pushing.” You are literally pushing the changes from your computer up in to the cloud. Only then will other people be able to download them./p>/blockquote>h3>6) Downloading/h3>p>The next difference is downloading. Can you spot the difference? Why, that’s right! While Dropbox downloads the new changes automatically, git waits for you to tell it too./p>blockquote classposterous_medium_quote>p>You must ask git explicitly to “pull” the changes down from the cloud to your computer. This gives you the latest greatest copy of the documents, including everyone else’s changes/p>/blockquote>p>Stay strong! Keep faith that even though there is seemingly less magic, and more work, there are reasons for all this mortal toil sic!/p>h3>Ordering, or 6… 4… 6… 5…???/h3>p>git requires you to operate with a slightly different order of operations because it is more manual (slightly less magic)./p>p>Before you start changing things, you want to make sure you have the latest and greatest version with everyone else’s changes. That means the first thing you want to do is download the latest stuff from the cloud (i.e. do a pull)./p>p>Now that you have the latest, you can change it and edit it to your heart’s content. When you are happy with your changes you are ready to tell git you’re happy (i.e. commit)./p>blockquote classposterous_short_quote>p>You can also rinse lather and repeat step 4 many times, committing small changes before going to the next step./p>/blockquote>p>But wait a second! What if Brian in marketing changed the document WHILE you were working on it? Because git doesn’t automatically download the changes, your computer (and you, by extension) doesn’t know about the new changes. So this adds another step, redownloading (i.e. doing another pull!)/p>p>Okay, now git knows about your changes, it knows about Brian’s changes, and the only thing left to do is… Push! Finally we can upload our changes to the cloud for everyone else to see and look at./p>h3>That’s the gist of git./h3>p>It’s like Dropbox, but you have to tell it to download, save, download, and upload each time. (Pull, stage & commit, pull, and push)/p>p>If you are digging it so far, let’s tackle some Advanced differences./p>h1>Advanced Differences/h1>p>There are some other model differences between git and dropbox. The first are conflicts: what happens when two people change the same file. Another big one is the fact that git is “distributed,” i.e. there is no company holding the cloud for you… there can even be multiple clouds./p>p>Here are some quick overviews of salient differences./p>h3>Time Travel/h3>p>Every commit makes a little tick on a timeline. git keeps track of EVERY little tick. That means you can zoom back in time, and watch as your document changes from day 0 to present. You can see every change, along with who made it, and what there “commit message” was. Pretty cool./p>blockquote classposterous_short_quote>p>git has multi-player undoYou can find out exactly who made the typo, and when and then fix it really easily. (git has really awesome tools for this too)./p>/blockquote>h3>Conflict/h3>p>What happens when Brian changed that file in the cloud, while you were working on it on your computer? Dropbox takes care of it magically in the cloud, now… it’s your job. The second step 6 (re-pulling changes from the cloud) in your work flow is when you are most likely to have “merge conflicts”./p>blockquote classposterous_medium_quote>p>Usually git is pretty magical and figures out what to do if both you and Brian were editing the same file.For example if he changed the title of the document, and you added some foot notes, git will figure it out. However, if you change your salary to $350,000, and Brian changes it to $40, git isn’t going to know what to do./p>/blockquote>p>If Brian pushed his change first, git will make you fix it. It will say: “Brian said you make $40 an hour, but you said you make $350,000, who’s right”. Your call. Fix it, save it (commit it) and push it it! (but do pull it in case Brian caught his error and changed it to $400,000 while you were typing)/p>h3>Meta Comments/h3>p>Every time you save (commit really) some changes, git asks you for a “commit message”. This is couple of sentences that describe the changes you made: a brief overview so that someone could review the list of changes to this document, without having to read the whole thing./p>h3>Style/h3>p>Because git is a little more manual, there are a few stylistic changes suggested to make everyone happy. First of all, small changes. You should commit every time you finish changing a coherent piece. I.e. if you are changing your salary, and Brian’s, first make one commit with your increase and a commit message like “merit based salary adjustments”, then adjust Brian’s with a commit message of “balance the budget”. Good (informative) commit messages are very appreciated in git land./p>p>Due to the nature of fixing conflicts, git also prefers text. Images are much harder for it (and you) to merge if both people change at once. So whenever possible use a text format (like html or markdown)./p>h1>Fin/h1>p>Well, I don’t know if I convinced you that you HAVE to use git, but hopefully you understand it a little better now. If you are already using it, hopefully now it makes a little more sense. At the very least, you are a step closer to being a friend and co-conspirator of git./p>/div> /section> ul class post_info floating > li>a hrefhttps://devblog.bu.mp/post/40786227079/git-for-dropbox-users-dont-be-afraid-11374 class timestamp has_caption with_title >12 years ago/a>/li> /ul> /section> /li> li classpost group > section classgroup caption_and_post_info > section classcaption group> h2>a hrefhttps://devblog.bu.mp/post/40786228793/easy-partial-screen-modals-on-ios>Easy partial screen modals on iOS/a>/h2> div classcont group>div classii gt>div>div style>div>em stylepadding: 0px; margin: 0px;>This post was written by Anders from Bump’s iOS team./em>/div>div>Say you would want to present a modal view on an iPhone but you don’t want it to be full screen. What do you do? Well, there is always the option of just not using presentModalViewController:animated: and performing the animations yourself which also in turn means maintaining view and controller hierarchy yourself. /div>p>/p>div>You could of course subclass UINavigationController and encapsulate all that complexity in a subclass. That would of course mean that you would need to update your code in all places that use the UINavigationController. Another similar approach would be to subclass UIView and override setFrame: to not allow the frame to be set to full screen. Again, that would mean updating all relevant views to subclass your new UIView subclass with the setFrame: logic./div>div>A different approach which lets you maintain your code pretty much unchanged requires you to change the way UINavigationController itself behaves. The following solution lets you set the frame of your UINavigationControllers view which will then be maintained even if a modal view controller is presented./div>p>/p>div>All you need to to is call a static initializer method on this new NPNavigationController class:/div>div>span stylecolor: #000000;>/span>BPNavigationController setup;/div>/div>/div>/div>p>/p>div>Now you can set the UINavigationControllers view frame. Like so:/div>div>span stylecolor: #4d8186;>navigation/span>.view.frame CGRectMake(0.0f, 20.0f, 320.0f, 440.0f);/div>p>/p>div>If at any later point you present a modal view controller in a navigation controller that modal view controller will only be as big as the frame of the navigations controllers view./div>div>How is this magic achieved? Behold:/div>p>/p>div>div classdata>table classlines highlight cellpadding0 styleborder-spacing: 0px;>tr>td classline_numbers> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 /td>td classline_data stylewidth: 100%;>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC1>///div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC2>// BPNavigationController.h/div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC3>// StatusBarSize/div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC4>///div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC5>// Created by Anders Borch on 10/16/11./div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC6>// Copyright © 2011 Bump. All rights reserved./div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC7>///div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC8> /div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC9>#import <UIKit/UIKit.h>/div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC10> /div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC11>@interface BPNavigationController : UINavigationController/div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC12> /div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC13>/*!/div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC14> @method setup/div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC15> @abstract Setup UINavigationController to handle non-fullscreen modals./div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC16> @discussion/div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC17> This will replace the implementation of presentModalViewController:animated: with a new implementation /div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC18> which retains the original frame of the UINavigationController#view and pushes a /div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC19> *//div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC20>+ (void)setup;/div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC21> /div>pre>/pre>div classline idfile-bpnavigationcontroller-h-LC22>@end/div>/td>/tr>/table>/div>/div>/div> /section> ul class post_info floating > li>a hrefhttps://devblog.bu.mp/post/40786228793/easy-partial-screen-modals-on-ios class timestamp has_caption with_title >12 years ago/a>/li> /ul> /section> /li> li classpost group > section classgroup caption_and_post_info > section classcaption group> h2>a hrefhttps://devblog.bu.mp/post/40786228091/who-said-android-apps-cant-look-good>Who said Android apps can’t look good?/a>/h2> div classcont group>p>em stylepadding: 0px; margin: 0px;>This post was written by Indy from Bump’s Android team./em>/p>p>Today we are releasing Bump 2.4 or what we have been calling the Visual Refresh. Earlier this year we hired our first (and so far only, a hrefhttp://bu.mp/jobs target_blank stylecolor: #0000cc;>we’re hiring/a>) badass visual designer, Shona Dutta. Since then she’s been on a crusade to make our apps and everything else we present (including the recent a hrefhttp://blog.bu.mp/thank-you-bump-users-all-50000000-of-you target_blank stylecolor: #0000cc;>span>infographic/span>/a>) look as awesome as our technology./p>p>So when it was time for the Android app to get it’s much needed facelift we wanted to jump on it right away. Unfortunately we were still finishing up some other major features in the app, so our team’s summer intern Will Whitney, cut a branch and started churning away (If you’re an awesome Android dev, this is why we need you, there are too many things to get done and we are currently only two people). He left about a month ago, and finally in the last two weeks we had the time to finish up the work he started./p>p>In the last 10 months we’ve learned a lot about the ins and outs and how to build a great app on Android. One of the things we learned quickly was people rightfully bagged on Android apps not looking as good as their iOS counterparts. But the reasons they pointed to were just plain wrong./p>p>It’s a common misunderstanding that Android apps are harder to program than iOS. People say it’s because the lifecycle behind Activities (Android’s rough equivalents of iOS UIViewControllers) are hard to work with. Not true, I think reading through the a hrefhttp://developer.android.com/reference/android/app/Activity.html target_blank stylecolor: #0000cc;>documentation/a> on that once should clear up a lot of confusion. People say it’s because the UI code is a bunch of messy xml. Not true, yes it’s xml, but it’s xml used in the way it should: declaratively and in a DRY manner. The xml based layouts are what make UI programming quite a lot nicer: one because it forces view code to be purely view code; two because simple parameter tweaking can produce great results./p>p>In fact I joke with our iOS team that android UI is ridiculously fast to iterate on. Case and point is the global network status bar we have on top of the new app. Whenever the network goes down or is unavailable on any screen of the app a thin black bar rolls down above the whole UI (squeezing the content area below it) letting the user know what went wrong. This simple squeezing of the UI and adding a view on top of every screen took less than two hours to put together./p>p>The real reason Android Apps historically haven’t looked good is because people haven’t put in the same care in building those apps. From a business sense that made sense in the past. Android has never been the primary platform for app users. But the rate of growth of the platform is phenomenal, and even if you believe that in general an Android user is less likely to use apps than an iOS user, the raw numbers should shock you into putting the same care into your Android app as your iOS app./p>p>So it’s finally here: a hrefhttps://market.android.com/details?idcom.bumptech.bumpga target_blank stylecolor: #0000cc;>Bump 2.4 for Android/a>. An App that finally looks as good as it works./p>div classp_embed p_image_embed>img altSs-480-1-7 height854 srchttp://getfile0.posterous.com/getfile/files.posterous.com/temp-2011-09-30/xAtEFcloBpaqCwiEIgdrdwxoicbFhBwlDCqenDdJbgBkJiuyyJHHniIbpIii/ss-480-1-7.jpeg.scaled500.jpg width480 />img altSs-480-2-6 height854 srchttp://getfile5.posterous.com/getfile/files.posterous.com/temp-2011-09-30/BtIosoFkibvsAuDIshgJFjBpwwBpCtJkjglmAyelxrHiqsbiBshHxbgcqyii/ss-480-2-6.jpeg.scaled500.jpg width480 />div classp_see_full_gallery>a hrefhttp://devblog.bu.mp/who-said-android-apps-cant-look-good>See the full gallery on Posterous/a>/div>/div>p> /p>/div> /section> ul class post_info floating > li>a hrefhttps://devblog.bu.mp/post/40786228091/who-said-android-apps-cant-look-good class timestamp has_caption with_title >12 years ago/a>/li> /ul> /section> /li> !-- END POSTS --> /ul> footer idfooter> section classcopyright>© 2013–2024 Bump Dev Blog/section> nav classpagination> section classbuttons> a href/page/2 classright>Next pagespan classarrow>/span>/a> /section> section classdisabled buttons> li classleft>span classarrow>/span>/li> li classright>span classarrow>/span>/li> /section> section classcount>Page 1 / 3/section> /nav> /footer> /section> script typetext/javascript srchttps://assets.tumblr.com/javascript/jquery-1.7.2.min.js>/script> script typetext/javascript> var Tumblelog {}; // AJAX Tumblelog.Ajax (function(url, callbackFunction) { this.bindFunction function (caller, object) { return function() { return caller.apply(object, object); }; }; this.stateChange function (object) { if (this.request.readyState4) this.callbackFunction(this.request.responseText); }; this.getRequest function() { if (window.ActiveXObject) return new ActiveXObject(Microsoft.XMLHTTP); else if (window.XMLHttpRequest) return new XMLHttpRequest(); return false; }; this.postBody (arguments2 || ); this.callbackFunctioncallbackFunction; this.urlurl; this.request this.getRequest(); if(this.request) { var req this.request; req.onreadystatechange this.bindFunction(this.stateChange, this); if (this.postBody!) { req.open(POST, url, true); req.setRequestHeader(X-Requested-With, XMLHttpRequest); req.setRequestHeader(Content-type, application/x-www-form-urlencoded); req.setRequestHeader(Connection, close); } else { req.open(GET, url, true); } req.send(this.postBody); } }); // Infinite Scroll Tumblelog.Infinite (function() { var _$window $(window); var _$posts $(#posts); var _trigger_post null; var _current_page 1; var _total_pages 3; var _url document.location.href; var _infinite_timeout null; var _is_loading false; var _posts_loaded false; var _Ajax Tumblelog.Ajax; function init() { set_trigger(); enable_scroll(); } function set_trigger () { var $all_posts _$posts.find(li.post); if (!_posts_loaded) { _posts_loaded $all_posts.length; } if (_posts_loaded > 4) { _trigger_post _$posts.find(li.post:eq( + ($all_posts.length - 4) + )).get(0); } else if (_posts_loaded > 3) { _trigger_post _$posts.find(li.post:eq( + ($all_posts.length - 3) + )).get(0); } else { _trigger_post _$posts.find(li.post:last).get(0); } }; function in_viewport (el) { if (el null) return; var top el.offsetTop; var height el.offsetHeight; while (el.offsetParent) { el el.offsetParent; top + el.offsetTop; } return (top (window.pageYOffset + window.innerHeight)); }; function enable_scroll() { $(#footer .pagination).hide(); _$window.scroll(function(){ clearTimeout(_infinite_timeout); infinite_timeout setTimeout(infinite_scroll, 100); }); } function disable_scroll() { clearTimeout(_infinite_timeout); $(window).unbind(scroll); } function infinite_scroll() { if (_is_loading) return; if (in_viewport(_trigger_post)) { load_more_posts(); // w00t } }; function load_more_posts() { if (_is_loading) return; _is_loading true; // Build URL if (_url.charAt(_url.length - 1) ! /) _url + /; if (_current_page 1) _url + page/1; _current_page++; _url _url.replace(page/ + (_current_page - 1), page/ + _current_page); // Fetch _Ajax(_url, function(data) { var new_posts_html data.split(!-- START + POSTS -->)1.split(!-- END + POSTS -->)0; var $new_posts $(#posts, data); // Insert posts and update counters $(#posts).append(new_posts_html); _posts_loaded $new_posts.find(li.post).length; if ((_posts_loaded > 0) && (_current_page _total_pages)) { set_trigger(); _is_loading false; } else { disable_scroll(); } }); // Stats } return { init: init }; }); $(function() { if ( !($.browser.msie && (parseInt($.browser.version, 10) 9) ) ) { var InfiniteScroll new Tumblelog.Infinite; InfiniteScroll.init(); } }); /script> script typetext/javascript srchttps://assets.tumblr.com/javascript/tumblelog.js>/script> !-- For Syntax Highlighting -->script srchttp://code.jquery.com/jquery-latest.min.js>/script>link relstylesheet typetext/css hrefhttp://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css>/link> script srchttp://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js>/script> iframe scrollingno width1 height1 frameborder0 stylebackground-color:transparent; overflow:hidden; position:absolute; top:0; left:0; z-index:9999; idga_target>/iframe>script typetext/javascript> (function(){ var analytics_frame document.getElementById(ga_target); var analytics_iframe_loaded; var user_logged_in; var blog_is_nsfw No; var eventMethod window.addEventListener ? addEventListener : attachEvent; var eventer windoweventMethod; var messageEvent eventMethod attachEvent ? onmessage : message; eventer(messageEvent,function(e) { var message (e.data && e.data.split) ? e.data.split(;) : ; switch (message0) { case analytics_iframe_loaded: analytics_iframe_loaded true; postCSMessage(); postGAMessage(); break; case user_logged_in: user_logged_in message1; postGAMessage(); break; } }, false); analytics_frame.src https://assets.tumblr.com/analytics.html?_v9f5febfd57a8a649c598d888f2d9e062# + https://devblog.bu.mp; function postGAMessage() { if (analytics_iframe_loaded && user_logged_in) { var is_ajax false; analytics_frame.contentWindow.postMessage(tick_google_analytics, is_ajax, user_logged_in, blog_is_nsfw, /?route%2F.join(;), analytics_frame.src.split(/analytics.html)0); } } function postCSMessage() { COMSCORE true; analytics_frame.contentWindow.postMessage(enable_comscore; + window.location, analytics_frame.src.split(/analytics.html)0); } })();/script>script typetext/javascript nonceSDQrPXOaNlHe4pJoT9LUoqVOHsE>!function(s){s.srchttps://px.srvcs.tumblr.com/impixu?T1726341232&JeyJ0eXBlIjoidXJsIiwidXJsIjoiaHR0cDovL2RldmJsb2cuYnUubXAvIiwicmVxdHlwZSI6MCwicm91dGUiOiIvIn0&UAOGNGNADLO&Ke583f5402adb1512e2f02af83b1d764bd4c3870630ad6e7b8f2a6e9c9b9b282c&R.replace(/&R^&$*/,).concat(&R+escape(document.referrer)).slice(0,2000).replace(/%.?.?$/,);}(new Image());/script>noscript>img styleposition:absolute;z-index:-3334;top:0px;left:0px;visibility:hidden; srchttps://px.srvcs.tumblr.com/impixu?T1726341232&JeyJ0eXBlIjoidXJsIiwidXJsIjoiaHR0cDovL2RldmJsb2cuYnUubXAvIiwicmVxdHlwZSI6MCwicm91dGUiOiIvIiwibm9zY3JpcHQiOjF9&UAOGNGNADLO&K90df1ec3549ae4bab7bbd42bdf79d0fba5037dfdcc286ddae5e4deab408ebcf5&R>/noscript>script typetext/javascript nonceSDQrPXOaNlHe4pJoT9LUoqVOHsE>!function(s){s.srchttps://px.srvcs.tumblr.com/impixu?T1726341232&JeyJ0eXBlIjoicG9zdCIsInVybCI6Imh0dHA6Ly9kZXZibG9nLmJ1Lm1wLyIsInJlcXR5cGUiOjAsInJvdXRlIjoiLyIsInBvc3RzIjpbeyJwb3N0aWQiOiI1MzUyOTY0NDQzOSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9LHsicG9zdGlkIjoiNDA3ODYyMjE5MDIiLCJibG9naWQiOjg5OTA3OTczLCJzb3VyY2UiOjMzfSx7InBvc3RpZCI6IjQwNzg2MjIzMTQ2IiwiYmxvZ2lkIjo4OTkwNzk3Mywic291cmNlIjozM30seyJwb3N0aWQiOiI0MDc4NjIyMzk4NSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9LHsicG9zdGlkIjoiNDA3ODYyMjQ2MDciLCJibG9naWQiOjg5OTA3OTczLCJzb3VyY2UiOjMzfSx7InBvc3RpZCI6IjQwNzg2MjI1NDc3IiwiYmxvZ2lkIjo4OTkwNzk3Mywic291cmNlIjozM30seyJwb3N0aWQiOiI0MDc4NjIyNjAxMSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9LHsicG9zdGlkIjoiNDA3ODYyMjcwNzkiLCJibG9naWQiOjg5OTA3OTczLCJzb3VyY2UiOjMzfSx7InBvc3RpZCI6IjQwNzg2MjI4NzkzIiwiYmxvZ2lkIjo4OTkwNzk3Mywic291cmNlIjozM30seyJwb3N0aWQiOiI0MDc4NjIyODA5MSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9XX0&UOCICJPPJPN&Kd8280d5463e6610a32864ab0fceef8733974ee307ca17faff976f21b2982079b&R.replace(/&R^&$*/,).concat(&R+escape(document.referrer)).slice(0,2000).replace(/%.?.?$/,);}(new Image());/script>noscript>img styleposition:absolute;z-index:-3334;top:0px;left:0px;visibility:hidden; srchttps://px.srvcs.tumblr.com/impixu?T1726341232&JeyJ0eXBlIjoicG9zdCIsInVybCI6Imh0dHA6Ly9kZXZibG9nLmJ1Lm1wLyIsInJlcXR5cGUiOjAsInJvdXRlIjoiLyIsInBvc3RzIjpbeyJwb3N0aWQiOiI1MzUyOTY0NDQzOSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9LHsicG9zdGlkIjoiNDA3ODYyMjE5MDIiLCJibG9naWQiOjg5OTA3OTczLCJzb3VyY2UiOjMzfSx7InBvc3RpZCI6IjQwNzg2MjIzMTQ2IiwiYmxvZ2lkIjo4OTkwNzk3Mywic291cmNlIjozM30seyJwb3N0aWQiOiI0MDc4NjIyMzk4NSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9LHsicG9zdGlkIjoiNDA3ODYyMjQ2MDciLCJibG9naWQiOjg5OTA3OTczLCJzb3VyY2UiOjMzfSx7InBvc3RpZCI6IjQwNzg2MjI1NDc3IiwiYmxvZ2lkIjo4OTkwNzk3Mywic291cmNlIjozM30seyJwb3N0aWQiOiI0MDc4NjIyNjAxMSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9LHsicG9zdGlkIjoiNDA3ODYyMjcwNzkiLCJibG9naWQiOjg5OTA3OTczLCJzb3VyY2UiOjMzfSx7InBvc3RpZCI6IjQwNzg2MjI4NzkzIiwiYmxvZ2lkIjo4OTkwNzk3Mywic291cmNlIjozM30seyJwb3N0aWQiOiI0MDc4NjIyODA5MSIsImJsb2dpZCI6ODk5MDc5NzMsInNvdXJjZSI6MzN9XSwibm9zY3JpcHQiOjF9&UOCICJPPJPN&K24fd3b65431728275b474d63a63c53bd4b7b0116e31d50226197302e8eb56765&R>/noscript>noscript idbootloader data-bootstrap{"Components":{"PostActivity":,"NotificationPoller":{"messaging_keys":,"token":"","inbox_unread":0},"DesktopDashboardLogo":{"animations":"https:\/\/assets.tumblr.com\/images\/logo\/hover-animations\/1.png?_v161861acded461bb6e995593a3bae835","https:\/\/assets.tumblr.com\/images\/logo\/hover-animations\/1@2x.png?_v496a774637302a598c851381d00009b0"},"TumblelogIframe":{"unified":true,"variant":null,"isCompact":true,"tumblelogBundleSrc":"https:\/\/assets.tumblr.com\/client\/prod\/standalone\/tumblelog\/index.build.js?_v03e800b27eff76cee863b8346f5e3e52","tumblelogName":"bumpdevblog","isLoggedIn":false,"isFriend":false,"formKey":"","canSubscribe":false,"isSubscribed":false,"tumblelogTitle":"Bump Dev Blog","tumblelogAvatar":"https:\/\/64.media.tumblr.com\/avatar_4f7f72a199bb_64.pnj","tumblelogAvatar128":"https:\/\/64.media.tumblr.com\/avatar_4f7f72a199bb_128.pnj","tumblelogHost":"https:\/\/devblog.bu.mp","hasCustomDomain":true,"isOptica":false,"isCustomTheme":true,"themeHeaderImage":"https:\/\/assets.tumblr.com\/images\/default_header\/optica_pattern_02_focused_v3.png?_vb976ee00195b1b7806c94ae285ca46a7","themeBackgroundColor":"#FFFFFF","themeTitleColor":"#000000","themeAccentColor":"#00B8FF","brag":true,"canShowAd":false,"isPremium":false,"showLrecAds":false,"showStickyLrecBackfill":false,"showGeminiAds":false,"geminiSectionCodeDesktop":"a10bca9c-0c5d-4a02-ab13-14ab8513d81d","geminiSectionCodeMobile":"ced63809-b609-4aca-96a0-abc099acba6b","currentPageType":"blog","currentPage":1,"searchQuery":"","tag":"","query":"","chrono":false,"postId":"","src":"https:\/\/devblog.bu.mp\/","postUrl":"","openInPeeprUrl":"https:\/\/www.tumblr.com\/bumpdevblog","isBlocked":null,"isAdmin":false,"lookupButtonUrl":"","showSpamButton":false,"showRootPostButton":false,"rootPostUrl":"","showRadarPostButton":false,"radarKeys":"","isUniblocked":false,"isNsfw":false,"isAdult":false,"isSpam":false,"isPrimaryBlog":false,"canEdit":false,"canReblogSelf":false,"showLikeButton":false,"showReblogButton":false,"reblogUrl":"","showMessagingButton":false,"loginCheckIframeSrc":"https:\/\/assets.tumblr.com\/assets\/html\/iframe\/login_check.html?_v3de94a184d600617102ddd5b48fb36e9","appInstallUrls":{"android":"https:\/\/play.google.com\/store\/apps\/details?idcom.tumblr\u0026referrerutm_source%3Dtumblr%26utm_medium%3Diframe%26utm_campaign%3Dbn_continue_or_install_cta","ios":"https:\/\/apps.apple.com\/app\/apple-store\/id305343404?pt212308\u0026ctbn_continue_or_install_cta\u0026mt8"},"appOpenReferrer":"bn_header_open_btn","isShowSearch":true,"supplyLogging":,"secondsSinceLastActivity":-1,"installUrlOpenFailed":{"android":"https:\/\/play.google.com\/store\/apps\/details?idcom.tumblr\u0026referrerutm_source%3Dtumblr%26utm_medium%3Diframe%26utm_campaign%3Dbn_header_app_open_failed","ios":"https:\/\/apps.apple.com\/app\/apple-store\/id305343404?pt212308\u0026ctbn_header_app_open_failed\u0026mt8"},"loginWallVariant":"small_center"},"CommunityLabels":{"has_community_label":false,"is_single":false,"redirect_target":null}},"Flags":{"features":"eyJmaWx0ZXJfbnNmdyI6dHJ1ZSwibW9iaWxlX3dlYl9nYXRlIjp0cnVlLCJzYWZlX21vZGUiOnRydWUsInNhZmVfbW9kZV9lbmFibGVkIjp0cnVlLCJrZXljb21tYW5kX2F1dG9fcGFnaW5hdGUiOnRydWUsImxvZ2dlZF9vdXRfc2VhcmNoIjp0cnVlLCJrcmFrZW5fd2ViX2xvZ2dpbmdfbGlicmFyeSI6dHJ1ZSwibGl2ZXBob3Rvc193ZWIiOnRydWUsInVzZXJfdGFnX2ZpbHRlcmluZyI6dHJ1ZSwic2FmZV9tb2RlX293bl9wb3N0Ijp0cnVlLCJwcm9qZWN0X3hfYXBwZWFsIjp0cnVlLCJtb2JpbGVfd2ViX3Bob3Rvc2V0cyI6dHJ1ZSwiaGlkZV9kZWZhdWx0X2hlYWRlcnNfYmxvZ19jYXJkcyI6dHJ1ZSwibm90aWZpY2F0aW9uX3JlcGx5X2xpbmtfdG9fbm90ZXMiOnRydWUsInR5cGluZ19pbmRpY2F0b3Jfd3JpdGUiOnRydWUsInR1bWJscl92aWRlb19zcG9uc29yZWRfZGF5Ijp0cnVlLCJjYXB0Y2hhOnVzZV9yZWNhcHRjaGEyIjp0cnVlLCJsaXR0bGVfc2lzdGVyIjp0cnVlLCJlbmFibGVfanNfZXJyb3JzX2xvZyI6dHJ1ZSwibG9nX2xhZHkiOnRydWUsImpzX3BlcmZvcm1hbmNlX2xvZ2dpbmciOnRydWUsInJlZHBvcF9wb3N0X2Zvcm1fbW9iaWxlX2NyZWF0ZSI6dHJ1ZSwibGVnYWN5X3Bvc3RfZm9ybV9idXR0b25zX2xpbmtfdG9fcmVkcG9wIjp0cnVlLCJzaG93X3RzcF9jbGlja190aHJvdWdoX3RvZ2dsZSI6dHJ1ZSwiZGFybGFfYWRfZmVlZGJhY2siOnRydWUsInN0YXR1c19pbmRpY2F0b3IiOnRydWUsImNvbnZlcnNhdGlvbmFsX25vdGlmaWNhdGlvbnMiOnRydWUsImRpc2FibGVfeWFob29fYl9jb29raWUiOnRydWUsImxpdmVwaG90b3MiOnRydWUsImNvbW11bml0eV9sYWJlbHMiOnRydWV9"},"Context":{"name":"default","time":1726341232000,"userinfo":{"primary":"","name":"","channels":},"hosts":{"assets_host":"https:\/\/assets.tumblr.com","secure_assets_host":"https:\/\/assets.tumblr.com","www_host":"https:\/\/www.tumblr.com","secure_www_host":"https:\/\/www.tumblr.com","embed_host":"https:\/\/embed.tumblr.com","safe_host":"https:\/\/safe.txmblr.com","platform_host":"https:\/\/platform.tumblr.com"},"language":"en_US","language_simple":"en","assets":"https:\/\/assets.tumblr.com\/client\/prod\/"},"Translations":{"%1$sReport %2$s's post?%3$sIf it violates our user guidelines, we'll remove it.%4$s":"%1$sReport %2$s's reblog?%3$sIf it violates our user guidelines, we'll remove it.%4$s","%1$sReport %2$s's reply?%3$sIf it violates our user guidelines, we'll remove it.%4$s":"%1$sReport %2$s's reblog?%3$sIf it violates our user guidelines, we'll remove it.%4$s","%1$sDelete your tip??%2$s":"%1$sDelete your tip?%2$s","Deleting your tip":"Deleting your tip will only remove it from the replies tab and notes. %1$sYou won't receive a refund of your tip.%2$s For further help contact %3$sTumblr Support%4$s."}}>/noscript>script srchttps://assets.tumblr.com/client/prod/standalone/tumblelog/index.build.js?_v03e800b27eff76cee863b8346f5e3e52>/script>/body>/html>
View on OTX
|
View on ThreatMiner
Please enable JavaScript to view the
comments powered by Disqus.
Data with thanks to
AlienVault OTX
,
VirusTotal
,
Malwr
and
others
. [
Sitemap
]