CINXE.COM

Google Open Source Blog: August 2018

<!DOCTYPE html> <html class='v2 no-js' dir='ltr' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'> <head> <link href='https://www.blogger.com/static/v1/widgets/3566091532-css_bundle_v2.css' rel='stylesheet' type='text/css'/> <!-- Google Tag Manager --> <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-5CNC9X8');</script> <!-- End Google Tag Manager --> <meta charset='utf-8'/> <meta content='IE=Edge' http-equiv='X-UA-Compatible'/> <meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, height=device-height' name='viewport'/> <link href='https://opensource.google.com/assets/static/images/favicon.png' rel='shortcut icon'/> <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/> <meta content='blogger' name='generator'/> <link href='https://opensource.googleblog.com/favicon.ico' rel='icon' type='image/x-icon'/> <link href='https://opensource.googleblog.com/2018/08/' rel='canonical'/> <link rel="alternate" type="application/atom+xml" title="Google Open Source Blog - Atom" href="https://opensource.googleblog.com/feeds/posts/default" /> <link rel="alternate" type="application/rss+xml" title="Google Open Source Blog - RSS" href="https://opensource.googleblog.com/feeds/posts/default?alt=rss" /> <link rel="service.post" type="application/atom+xml" title="Google Open Source Blog - Atom" href="https://www.blogger.com/feeds/8698702854482141883/posts/default" /> <!--Can't find substitution for tag [blog.ieCssRetrofitLinks]--> <meta content='https://opensource.googleblog.com/2018/08/' property='og:url'/> <meta content='Google Open Source Blog' property='og:title'/> <meta content='' property='og:description'/> <title>Google Open Source Blog: August 2018</title> <meta content='Google Open Source Blog' property='twitter:title'/> <meta content='https://opensource.google.com/assets/static/images/home/blog/blog_image_1.jpg' property='og:image'/> <meta content='en_US' property='og:locale'/> <meta content='Google Open Source Blog' property='og:site_name'/> <meta content='summary' name='twitter:card'/> <meta content='@GoogleOSS' name='twitter:creator'/> <meta content='@GoogleOSS' name='twitter:site'/> <style id='page-skin-1' type='text/css'><!-- --></style> <style id='template-skin-1' type='text/css'><!-- body { min-width: 860px; } .content-outer, .content-fauxcolumn-outer, .region-inner { min-width: 860px; max-width: 860px; _width: 860px; } .main-inner .columns { padding-left: 0px; padding-right: 260px; } .main-inner .fauxcolumn-center-outer { left: 0px; right: 260px; /* IE6 does not respect left and right together */ _width: expression(this.parentNode.offsetWidth - parseInt("0px") - parseInt("260px") + 'px'); } .main-inner .fauxcolumn-left-outer { width: 0px; } .main-inner .fauxcolumn-right-outer { width: 260px; } .main-inner .column-left-outer { width: 0px; right: 100%; margin-left: -0px; } .main-inner .column-right-outer { width: 260px; margin-right: -260px; } #layout { min-width: 0; } #layout .content-outer { min-width: 0; width: 800px; } #layout .region-inner { min-width: 0; width: auto; } body#layout div.add_widget { padding: 8px; } body#layout div.add_widget a { margin-left: 32px; } --></style> <script type='text/javascript'> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-53341410-4', 'auto', 'blogger'); ga('blogger.send', 'pageview'); </script> <link href='https://fonts.googleapis.com/css?family=Google+Sans|Roboto+Slab:300,500,900|Roboto:400italic,400,500,500italic,700,700italic' rel='stylesheet'/> <link href='https://fonts.googleapis.com/icon?family=Material+Icons' rel='stylesheet'/> <!-- OGC styles with data uri --> <style type='text/css'> .footer-main .google a { background: url("data:image/svg+xml,%3C%3Fxml%20version%3D%271.0%27%20encoding%3D%27utf-8%27%3F%3E%0A%3Csvg%20version%3D%271.1%27%20id%3D%27content%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%0A%09%20viewBox%3D%270%200%20416%20139.5%27%20style%3D%27enable-background%3Anew%200%200%20416%20139.5%3B%27%20xml%3Aspace%3D%27preserve%27%3E%0A%3Cstyle%20type%3D%27text%2Fcss%27%3E%0A%09.st0%7Bfill%3A%23FFFFFF%3B%7D%0A%3C%2Fstyle%3E%0A%3Csymbol%20%20id%3D%27logo_x5F_dark%27%20viewBox%3D%270.7%20-135.4%20414.8%20135.3%27%3E%0A%09%3Cpath%20class%3D%27st0%27%20d%3D%27M0.7-52.6C0.7-23.6%2C25-0.1%2C54-0.1c16%2C0%2C27.4-6.3%2C36-14.5L79.8-24.7C73.7-18.9%2C65.4-14.4%2C54-14.4%0A%09%09c-21.1%2C0-37.6-17-37.6-38.1c0-21.1%2C16.5-38.1%2C37.6-38.1c13.7%2C0%2C21.5%2C5.5%2C26.5%2C10.5c4.1%2C4.1%2C6.8%2C10%2C7.8%2C18H54v14.3h48.3%0A%09%09c0.5-2.6%2C0.8-5.6%2C0.8-9c0-10.8-2.9-24.1-12.4-33.5C81.4-99.9%2C69.6-105%2C54-105C25-105%2C0.7-81.5%2C0.7-52.6z%27%2F%3E%0A%09%3Cpath%20class%3D%27st0%27%20d%3D%27M142-37.5c-18.7%2C0-33.9-14.2-33.9-33.8c0-19.5%2C15.2-33.8%2C33.9-33.8c18.7%2C0%2C33.9%2C14.3%2C33.9%2C33.8%0A%09%09C175.9-51.7%2C160.7-37.5%2C142-37.5z%20M142-91.7c-10.2%2C0-19.1%2C8.4-19.1%2C20.5c0%2C12.2%2C8.8%2C20.5%2C19.1%2C20.5c10.2%2C0%2C19.1-8.3%2C19.1-20.5%0A%09%09C161.1-83.3%2C152.2-91.7%2C142-91.7z%27%2F%3E%0A%09%3Cpath%20class%3D%27st0%27%20d%3D%27M216-37.5c-18.7%2C0-33.9-14.2-33.9-33.8c0-19.5%2C15.2-33.8%2C33.9-33.8c18.7%2C0%2C33.9%2C14.3%2C33.9%2C33.8%0A%09%09C249.9-51.7%2C234.7-37.5%2C216-37.5z%20M216-91.7c-10.2%2C0-19.1%2C8.4-19.1%2C20.5c0%2C12.2%2C8.8%2C20.5%2C19.1%2C20.5s19.1-8.3%2C19.1-20.5%0A%09%09C235.1-83.3%2C226.2-91.7%2C216-91.7z%27%2F%3E%0A%09%3Cpath%20class%3D%27st0%27%20d%3D%27M306.8-39.5V-45h-0.5c-3.3%2C4-9.7%2C7.6-17.8%2C7.6c-16.9%2C0-32.4-14.8-32.4-33.9c0-18.9%2C15.5-33.7%2C32.4-33.7%0A%09%09c8.1%2C0%2C14.5%2C3.6%2C17.8%2C7.7h0.5v-4.9c0-12.9-6.9-19.8-18-19.8c-9.1%2C0-14.7%2C6.5-17%2C12l-12.9-5.4c3.7-9%2C13.6-20%2C30-20%0A%09%09c17.4%2C0%2C32.1%2C10.2%2C32.1%2C35.2v60.7H306.8z%20M289.8-91.7c-10.2%2C0-18.8%2C8.6-18.8%2C20.4c0%2C11.9%2C8.6%2C20.6%2C18.8%2C20.6c10.1%2C0%2C18-8.7%2C18-20.6%0A%09%09C307.9-83.2%2C299.9-91.7%2C289.8-91.7z%27%2F%3E%0A%09%3Crect%20x%3D%27331.2%27%20y%3D%27-103%27%20class%3D%27st0%27%20width%3D%2714.8%27%20height%3D%2799.3%27%2F%3E%0A%09%3Cpath%20class%3D%27st0%27%20d%3D%27M386.7-91.7c-7.6%2C0-12.9%2C3.5-16.4%2C10.2l45.2%2C18.7L414-59c-2.8%2C7.6-11.4%2C21.5-28.9%2C21.5%0A%09%09c-17.4%2C0-31.9-13.7-31.9-33.8c0-18.9%2C14.3-33.8%2C33.5-33.8c15.5%2C0%2C24.4%2C9.5%2C28.2%2C15l-11.5%2C7.7C399.5-88%2C394.3-91.7%2C386.7-91.7z%0A%09%09%20M385.6-50.5c5.9%2C0%2C10.9-2.9%2C12.5-7.2l-30.2-12.5C367.5-57.2%2C378-50.5%2C385.6-50.5z%27%2F%3E%0A%3C%2Fsymbol%3E%0A%3Cuse%20xlink%3Ahref%3D%27%23logo_x5F_dark%27%20%20width%3D%27414.8%27%20height%3D%27135.3%27%20id%3D%27XMLID_1_%27%20x%3D%270.7%27%20y%3D%27-135.4%27%20transform%3D%27matrix(1%200%200%20-1%200%201)%27%20style%3D%27overflow%3Avisible%3B%27%2F%3E%0A%3C%2Fsvg%3E%0A") 0 0 no-repeat; } </style> <!-- OGC styles --> <style type='text/css'> #ogc-shim { display: none; visibility: hidden; } body { background-color: white; color: #444; font-family: "Roboto", sans-serif; min-width: 300px; line-height: 18px; margin: 0; padding: 0; -webkit-font-smoothing: antialiased; } body .container { overflow-x: hidden; } body a { color: #4285f4; font-weight: 500; text-decoration: none; } body div, body p, body ol { color: #444; font-size: 16px; line-height: 22px; margin: 0 0 33px 0; } body div { margin: 0; } body h1 { color: #444; font-family: "Roboto",sans-serif; font-size: 34px; font-weight: 300; line-height: 44px; margin: 0 0 33px 0; padding: 0; } body h1, body h2, body h3, body h4, body h5, body h6 { color: #444; font-family: "Google Sans",sans-serif; letter-spacing: -.01em; font-size: 34px; font-weight: 400; line-height: 44px; margin: 0 0 33px 0; padding: 0; } body ul { list-style: none; margin: 0; padding: 0; } body #whatbrowser { background: white; height: 100%; padding: 50px 15px; position: fixed; width: 100%; z-index: 300; } .header-main { background-color: #ffffff; height: 75px; line-height: 75px; position: relative; } .header-main a { color: #4c4c4c; text-decoration: none; } .header-main h1 { margin: 21px -250px 0 0; position: absolute; right: 100%; text-indent: -9999px; transition: all 0.3s ease-out; } .header-main h1 a { /* background: url(https://opensource.google.com/assets/static/images/logo_dark.svg) 0 0 no-repeat; */ background: url(https://www.gstatic.com/devrel-devsite/stage/v93a6dcf50ad5e38e51034415df5b4a8345b5c8613f785e48818ae468dabf73c8/opensource/images/lockup.svg) 0 0 no-repeat; background-size: 240px auto; display: block; height: 32px; line-height: 75px; width: 240px; } .nav-active { overflow: hidden; position: fixed; } .nav-active .main-nav { transform: translate(0, 0); } .nav-active #ShadowBox { display: block; } #ShadowBox { background: rgba(51,51,51,0.8); content: '[]'; display: none; height: 100vh; left: 0; position: absolute; text-indent: -9999px; top: 0; width: 100vw; z-index: 98; } .main-nav { background: #ffffff; height: 100vh; list-style: none; margin: 0; overflow: scroll; padding: 0; position: fixed; right: 0; top: 75px; transform: translate(277px, 0); transition: transform 0.2s ease-in; width: 277px; z-index: 300; } .main-nav ul { border-top: solid 4px #f2f2f2; min-height: 360px; padding-top: 10px; } .main-nav ul li { line-height: 55px; } .main-nav ul li a { background: white; display: block; font-size: 14px; padding: 0 30px; } .main-nav ul li a:hover, .main-nav ul li a:focus { color: #4285f4; } #NavTrigger { height: 48px; padding-top: 27px; position: absolute; right: 0; text-align: left; top: 0; width: 40px; } #NavTrigger:before, #NavTrigger:after, #NavTrigger span { background: #4c4c4c; border-radius: 50%; content: '.'; height: 4px; line-height: 4px; margin: 2px auto; width: 4px; display: block; overflow: hidden; text-indent: -9999px; } .main { background-color: #ffffff; box-shadow: 0 1px 1.5px rgba(0,0,0,0.12), 0 1px 1px rgba(0,0,0,0.24); box-sizing: border-box; margin: 0 auto; min-height: 100vh; } .col-wrap { margin: 0 auto; max-width: 988px; width: 100%; } .col-wrap:after { clear: both; content: ""; display: table; } .google-open-source { text-align: center; } .google-open-source .content { text-align: left; } .google-open-source .cols-wrapper { text-align: left; } .google-open-source section { padding: 35px 15px 15px 15px; } div.section#header { margin: inherit; } div.widget#Header1 { margin: inherit; line-height: inherit; } section.hero { background-color: #F8F9FA; box-sizing: border-box; color: #202124; display: flex; flex-direction: column; height: 338px; min-height: 338px; justify-content: center; margin: 0 auto; padding: 15px; position: relative; text-align: left; -ms-flex-align: center; } .hero:after { background: url("https://opensource.google.com/assets/static/images/home/hero-tall-mobile.png") 0 0 no-repeat; background-size: 257px 393px; content: '.'; font-size: 0; height: 393px; left: -15px; position: absolute; top: 0; width: 257px; } .short + .hero { height: 100%; min-height: 300px; } .short + .hero:after { display: none; } .short + .hero .col { display: -ms-flexbox; display: flex; flex-direction: column; height: 300px; justify-content: center; -ms-flex-align: center; } .short + .hero h2, .short + .hero h2 a { text-align: left !important; font-size: 56px !important; line-height: 48px !important; margin-bottom: 40px !important; color: #202124 !important; font-family: "Google Sans", sans-serif; text-decoration: none; } .short + .hero p { color: #202124; font-family: "Google Sans", sans-serif; font-size: 16px; line-height: 21px; margin-bottom: 0; max-width: 700px; z-index: 1; position: relative; } .hero h2 { color: #202124; margin: 0 0 8px 0; } .google-open-source section.hero h2 { font-size: 34px; line-height: 40px; margin-bottom: 20px; } .google-open-source section.hero h2.logo { background-size: 290px 36px; display: block; font-size: 0; height: 36px; text-indent: -9999px; width: 290px; } .hero p { color: #202124; font-family: "Roboto",sans-serif; font-size: 24px; line-height: 32px; } .hero .col-wrap { display: block !important; max-width: 1200px; } .google-open-source section p { font-size: 16px; margin: 0 auto 30px auto; } h2.archive-header { font-size: 32px; line-height: 40px; margin-bottom: 16px; } .google-open-source .main-inner .column-center-inner { padding: 0 15px 0 0; } .google-open-source .main-inner .column-center-inner .section { margin: 0 15px 0 0; } /*.google-open-source section.hero p { font-size: 18px; line-height: 24px; margin: 0; max-width: 240px; }*/ .post-footer .share { text-align: right; margin-bottom: 1em; } .post-footer .share img { margin-left: 12px; } .fb-custom img, .twitter-custom img, .gplus-share img { opacity: 0.54; cursor: pointer; } .fb-custom:hover img, .fb-custom:focus img, .twitter-custom:hover img, .twitter-custom:focus img, .gplus-share:hover img, .gplus-share:focus img { opacity: 1; } .footer-main { background-color: #474747; box-sizing: border-box; color: #ffffff; padding: 24px 15px; position: relative; z-index: 98; } .footer-main .col-wrap { max-width: none; } .footer-main nav li { display: inline-block; line-height: 25px; margin: 0 15px 0 0; } .footer-main a { color: #ccc; font-size: 14px; text-decoration: none; text-transform: uppercase; } .footer-main a:hover, .footer-main a:focus { color: white; } .footer-main .google { display: block; margin-bottom: 15px; } .footer-main .google a { display: inline-block; height: 26px; opacity: 0.54; text-indent: -9999px; width: 80px; } .pull-left { float: left; } @media (min-width: 720px) { body h1, body h2 { font-size: 44px; line-height: 54px; } .main-nav { float: right; height: 48px; overflow: hidden; position: inherit; top: -14px; transform: translate(0, 0); width: auto; right: unset; left: 350px; } .main-nav ul { border: none; padding: 0; } .main-nav ul li { display: inline-block; line-height: 48px; margin: 0 15px 0 0; } .main-nav ul li a { display: inline-block; padding: 0; } #NavTrigger { display: none; } .google-open-source section.hero { text-align: left; } body .hero:before { background: url(https://opensource.google/images/featured-blogs-icon.svg) 0px 0 no-repeat; background-size: 575px 85px; background-position-y: center; content: '.'; display: block; height: 100%; position: absolute; right: -10px; text-indent: -99999px; top: 0; width: 635px; } .short + .hero { height: 300px; } .google-open-source section.hero h2 { font-size: 46px; line-height: 52px; } .google-open-source section.hero h2.logo { background-size: 582px 72px; float: right; font-size: 0; height: 72px; width: 582px; } .google-open-source section p { max-width: 642px; } .google-open-source section.hero p { margin: 0 0 0px 0; } .footer-main nav .google { display: inline-block; margin-bottom: 0; } .header-main { height: 48px; } .header-main h1 { margin: 8px -265px 0 0; } .main.google-open-source { margin-top: 48px !important; } } @media (min-width: 940px) { body h1, body h2 { font-size: 52px; } .main-nav ul li { margin: 0 36px 0 0; } section.hero { opacity: 1; height: 600px; transition: opacity 0.4s ease-in; } /*body.item .hero:before, */ body.archive .hero:before { background-position: 0 0; } .hero h2 { opacity: 1; transition: opacity 0.4s ease-in 0.4s; } .google-open-source section.hero h2 { font-size: 52px; line-height: 58px; } .google-open-source .hero h2, .google-open-source .hero p { position: relative; } .google-open-source .hero h2:before, .google-open-source .hero p:before, .google-open-source .hero p:after { background: #474747; /*content: '|';*/ /* XXX not sure why this borks here, but works on OGC. or why it's necessary on OGC */ position: absolute; width: 100%; height: 100px; right: 0; text-indent: 99999px; transition: width 0.5s ease-in; } .google-open-source .hero h2:before { transition-delay: 0.5s; width: 87%; } .google-open-source .hero p:before, .google-open-source .hero p:after { height: 31px; transition-duration: 0.5s; transition-delay: 1s; } .google-open-source .hero p:after { transition-delay: 1.4s; } .google-open-source .hero:after { display: none; } .line-graphic { height: 600px; left: 0; position: absolute; top: 0; width: 100%; } .line-graphic .segment { width: 0; position: absolute; transition: width 0.25s ease-in; transition-delay: 1s; } .line-graphic .hotspot { height: 0; opacity: 0; transform: scale(1); transition: all 0.5s ease-in; transition-delay: 1 + 0.15s * 12; width: 0; } .line-graphic .hotspot:after { pointer-events: none; } .js .hero, .js .hero h2 { opacity: 1; } .js .hero h2:before, .js .hero p:before, .js .hero p:after { width: 0; } .js .line-graphic .blue-one { background: url("https://opensource.google.com/assets/static/images/home/hero/blue-1.png") 0 0 no-repeat; background-size: 381px 33px; width: 381px; height: 33px; top: 111px; left: -15px; transition-delay: 1 + 0.15s * 6; transition-duration: 0.25s * 2; } .js .line-graphic .grey-one { background: url("https://opensource.google.com/assets/static/images/home/hero/grey-1.png") 0 0 no-repeat; background-size: 232px 38px; width: 232px; height: 38px; top: 79px; left: 111px; transition-delay: 1 + 0.15s * 7; transition-duration: 0.25s * 1.5; } .js .line-graphic .grey-two { background: url("https://opensource.google.com/assets/static/images/home/hero/grey-2.png") 0 0 no-repeat; background-size: 100px 18px; width: 100px; height: 18px; top: 224px; left: -15px; transition-delay: 1 + 0.15s * 2; } .js .line-graphic .yellow-one { background: url("https://opensource.google.com/assets/static/images/home/hero/yellow-1.png") 0 0 no-repeat; background-size: 253px 21px; width: 253px; height: 21px; top: 322px; left: -15px; transition-delay: 1 + 0.15s * 3; } .js .line-graphic .grey-three { background: url("https://opensource.google.com/assets/static/images/home/hero/grey-3.png") 0 0 no-repeat; background-size: 100px 101px; width: 100px; height: 101px; top: 222px; left: 78px; transition-delay: 1 + 0.15s * 4; } .js .line-graphic .red-one { background: url("https://opensource.google.com/assets/static/images/home/hero/red-1.png") 0 0 no-repeat; background-size: 358px 49px; width: 358px; height: 49px; top: 139px; left: -15px; transition-delay: 1 + 0.15s * 6; transition-duration: 0.25s * 2; } .js .line-graphic .grey-four { background: url("https://opensource.google.com/assets/static/images/home/hero/grey-4.png") 0 0 no-repeat; background-size: 143px 49px; width: 143px; height: 49px; top: 340px; left: 78px; transition-delay: 1 + 0.15s * 6; } .js .line-graphic .green-one { background: url("https://opensource.google.com/assets/static/images/home/hero/green-1.png") 0 0 no-repeat; background-size: 251px 86px; width: 251px; height: 86px; top: 387px; left: 202px; transition-delay: 1 + 0.15s * 7; } .js .line-graphic .blue-two { background: url("https://opensource.google.com/assets/static/images/home/hero/blue-2.png") 0 0 no-repeat; background-size: 323px 25px; width: 323px; height: 25px; position: absolute; top: 115px; left: 371px; transition-delay: 1 + 0.15s * 10; } .js .line-graphic .grey-five { background: url("https://opensource.google.com/assets/static/images/home/hero/grey-5.png") 0 0 no-repeat; background-size: 141px 53px; width: 141px; height: 53px; top: 466px; left: 282px; transition-delay: 1 + 0.15s * 9; } .js .line-graphic .grey-six { background: url("https://opensource.google.com/assets/static/images/home/hero/grey-6.png") 0 0 no-repeat; background-size: 178px 118px; width: 178px; height: 118px; top: 0; left: 497px; transition-delay: 1 + 0.15s * 11; } .js .line-graphic .green-two { background: url("https://opensource.google.com/assets/static/images/home/hero/green-2.png") 0 0 no-repeat; background-size: 276px 142px; width: 276px; height: 142px; top: 515px; left: 394px; transition-delay: 1 + 0.15s * 11; } .js .line-graphic .grey-seven { background: url("https://opensource.google.com/assets/static/images/home/hero/grey-7.png") 0 0 no-repeat; background-size: 174px 93px; width: 174px; height: 93px; margin-left: -174px; top: 0; left: 100%; transition-delay: 1 + 0.15s * 12; } .js .line-graphic .grey-eight { background: url("https://opensource.google.com/assets/static/images/home/hero/grey-8-interactive.png") 0 0 no-repeat; background-size: 184px 17px; width: 184px; height: 17px; top: 23px; left: 681px; transition-delay: 0s; } .js .line-graphic .yellow-two { background: url("https://opensource.google.com/assets/static/images/home/hero/yellow-2-interactive.png") 0 0 no-repeat; background-size: 140px 25px; width: 140px; height: 25px; top: 319px; left: 244px; transition-delay: 0s; } .js .line-graphic .hidden { width: 0; } .js .line-graphic .hotspot { height: 40px; position: absolute; top: 12px; left: 645px; opacity: 1; transform: scale(1); width: 40px; } .js .line-graphic .hotspot::after { content: 'o'; display: block; background: $color-grey; border-radius: 50%; width: 40px; height: 40px; opacity: 0.4; text-indent: 9999px; animation: pulse 3.5s infinite; animation-delay: 0.5s; } .js .line-graphic .hotspot.yellow { top: 312px; left: 210px; } .js .line-graphic .hotspot.yellow::after { background: #fabb05; animation-delay: 0s; } @keyframes pulse { 0% { opacity: 0.3; transform: scale(1); } 20% { opacity: 0.1; transform: scale(0.3); } 80% { opacity: 0.1; transform: scale(0.3); } 100% { opacity: 0.3; transform: scale(1); } } .footer-main { padding: 24px; } } </style> <!-- OGC sticky header --> <style type='text/css'> .header-main { position: fixed; top: 0; width: 100%; box-shadow: 0 0 4px rgba(0,0,0,.14), 0 4px 8px rgba(0,0,0,.28); z-index: 200; } .main.google-open-source { margin-top: 75px; z-index: 100; } </style> <!-- OGC blog content and sidebar styles --> <style type='text/css'> body .sidebar .widget div { font-size: 16px; } .sidebar .searchBox input { border: 1px solid #eee; color: #212121; color: rgba(0,0,0,.87); font-size: 16px; padding: 8px 8px 8px 40px; width: 150px; font-family: Roboto, sans-serif; background: url(https://www.gstatic.com/images/icons/material/system/1x/search_grey600_24dp.png) 8px center no-repeat; } .sidebar .subscribe h2 { margin-bottom: 0 !important; } .sidebar .popular-posts ul { padding: 0; } .sidebar .popular-posts ul li { padding: 0 0 1em 0 !important; } .sidebar-icon { display: inline-block; height: 24px; width: 24px; vertical-align: middle; margin-right: 12px; margin-top: -1px; } .sidebar .subscribe img { opacity: 0.54; } .sidebar .share img { margin-right: 12px; opacity: 0.54; } .sidebar .share a:hover img, .sidebar .share a:focus img, .sidebar .subscribe:hover img, .sidebar .subscribe:focus img { opacity: 1; } .sidebar .widget { margin: 0; padding: 15px 0; min-height: 20px; border-bottom: 1px solid #eee; } .sidebar.section:first-child .widget:first-child { border-bottom: 0; } .sidebar.section:last-child .widget:last-child { border-bottom: 0; } .sidebar .widget a { font-weight: 100; color: #444; } .sidebar .widget a:focus, .sidebar .widget a:hover { color: #4285f4; } .sidebar .widget h2 { color: #444; font-family: "Google Sans", sans-serif; padding-bottom: 3px; font-size: 18px; line-height: 24px; margin-bottom: 16px; font-weight: 500; display: inline-block; text-decoration: none; } .widget.PopularPosts h2:before { content: url(https://www.gstatic.com/images/icons/material/system/1x/star_grey600_24dp.png); position: relative; top: 5px; padding: 0 10px 0 0; } .sidebar .student_programs { text-align: center; font-size: 14px !important; } .widget.PopularPosts ul li:last-child { padding-bottom: 5px !important; } .widget.BlogArchive { padding-bottom: 0px !important; } .widget.BlogArchive .widget-content { display: none; } .widget.BlogArchive h2 { display: block !important; cursor: pointer; } .widget.BlogArchive h2:before { content: url(https://www.gstatic.com/images/icons/material/system/1x/folder_grey600_24dp.png); position: relative; top: 5px; padding: 0 10px 0 0; } .widget.BlogArchive h2:after { content: url(https://www.gstatic.com/images/icons/material/system/1x/keyboard_arrow_down_grey600_24dp.png); position: absolute; right: 0; top: 7px; } .widget.BlogArchive.active h2:after { content: url(https://www.gstatic.com/images/icons/material/system/1x/keyboard_arrow_up_grey600_24dp.png); } #ArchiveList .toggle { float: right; color: rgba(0,0,0, 0.54) !important; } .BlogArchive #ArchiveList ul li { padding-left: 0px !important; text-indent: 0px !important; } .BlogArchive .post-count { color: #444; } .BlogArchive .post-count-link:hover { color: #444 !important; } .BlogArchive .intervalToggle { cursor: pointer; } .BlogArchive .expanded .intervalToggle .new-toggle { -ms-transform: rotate(180deg); transform: rotate(180deg); } .BlogArchive .new-toggle { float: right; padding-top: 3px; opacity: 0.87; } #ArchiveList .expanded > ul:last-child { margin-bottom: 16px; } #ArchiveList .archivedate { width: 100%; } .content-outer, .region-inner { /* min-width is 860, should be 300 to accommodate mobile */ position: relative; max-width: 988px; margin: 0 auto; } .date-outer + .date-outer, .post-footer + .post-outer { margin-top: 33px; padding-top: 33px; } pre.prettyprint { white-space: pre-wrap; } h4.date-header { color: #474747; font-size: 16px; line-height: 16px; font-weight: 100; font-family: "Google Sans", sans-serif; } h3.post-title { font-family: "Google Sans", sans-serif; font-size: 28px; line-height: 40px; margin-bottom: 16px; font-weight: 400; } body h3.post-title a { font-weight: 400; } .post .post-body { font-size: 16px; line-height: 1.5em; } .post-body img { max-width: 100%; height: auto; } div.separator a { max-width: 50%; } .post .post-body h2, .post .post-body h3, .post .post-body h4 { margin: 1em 0; } .post .post-body h2 { font-size: 24px; line-height: 24px; } .post .post-body h3 { font-size: 20px; line-height: 20px; } .post .post-body h4 { font-size: 16px; line-height: 16px; } .post .post-body p { max-width: inherit; margin: 1em 0; line-height: 1.5em; } .post .post-body ol, .post .post-body ul { margin: 1em 0; } .post .post-body ul { list-style-type: disc; } .post .post-body blockquote { font-style: italic; } .post .post-body pre, .post .post-body code { line-height: 1.25em; display: block; margin: 1em 0; } .post .post-body .intrinsic-container { position: relative; height: 0; overflow: hidden; } /* 16x9 Aspect Ratio */ .post .post-body .intrinsic-container-16x9 { padding-bottom: 56.25%; } /* 4x3 Aspect Ratio */ .post .post-body .intrinsic-container-4x3 { padding-bottom: 75%; } .post .post-body .intrinsic-container iframe { position: absolute; top:0; left: 0; width: 100%; height: 100%; } .post .post-body table.tr-caption-container[style*="float: right"], .post .post-body table.tr-caption-container[style*="float:right"], .post .post-body table.tr-caption-container[style*="float: left"], .post .post-body table.tr-caption-container[style*="float:left"] { width: auto; display: inline-block; } .post .post-body table { margin: 1em 0; width: 100%; } .post .post-body table thead { vertical-align: top; font-weight: 900; } .post .post-body table tbody { vertical-align: top; font-size: 14px; } .post .post-body table .tr-caption { text-align: center; font-style: italic; font-size: 14px; } div.post-footer { margin-top: 33px; } /* Home, forward, and backward pagination. */ .blog-pager { border-top : 1px #e0e0e0 solid; padding-top: 10px; margin-top: 15px; text-align: right !important; } #blog-pager { margin-botom: 0; margin-top: -14px; padding: 16px 0 0 0; } #blog-pager a { display: inline-block; } .blog-pager i.disabled { opacity: 0.2 !important; } .blog-pager i { color: black; margin-left: 16px; opacity: 0.54; } .blog-pager i:hover, .blog-pager i:active { opacity: 0.87; } #blog-pager-older-link, #blog-pager-newer-link { float: none; } #blog-pager { margin: 0; padding: 16px 0; } .list-page #blog-pager { padding-top: 0; border: 0; margin-top: -8px; } .labels-caption { font-weight: 500; } .labels a { font-weight: 100; } .label-footer { margin-bottom: 12px; margin-top: 12px; } @media (max-width: 720px) { .column-right-outer { display: none; } .content-outer, .region-inner { min-width: 300px; } .main-inner .columns { padding-right: inherit; } } </style> <style type='text/css'> .gci_winner_table, .table1 { border-collapse: collapse; border: none; text-align: left; } .gci_winner_table td, .gci_winner_table th, .table1 td, .table1 th { border: 1px solid #999999; } .gci_winner_table thead td, .gci_winner_table thead th, .table1 thead td, .table1 thead th { background-color: #d0e0e3; font-weight: 900; padding: 7px 7px 7px 3px; } .gci_winner_table tbody td, .table1 tbody td { padding: 3px; } .gci_winner_table td.column_separator, .table1 td.column_separator { background-color: transparent !important; border: 0px !important; } </style> <link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=8698702854482141883&amp;zx=e63597e9-8c01-4698-b2f8-f152e23b2226' media='none' onload='if(media!=&#39;all&#39;)media=&#39;all&#39;' rel='stylesheet'/><noscript><link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=8698702854482141883&amp;zx=e63597e9-8c01-4698-b2f8-f152e23b2226' rel='stylesheet'/></noscript> <meta name='google-adsense-platform-account' content='ca-host-pub-1556223355139109'/> <meta name='google-adsense-platform-domain' content='blogspot.com'/> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?display=swap&family=Roboto&family=Courier&family=Roboto+Mono&family=Consolas"></head> <body class='archive'> <!-- Google Tag Manager (noscript) --> <noscript><iframe height='0' src='https://www.googletagmanager.com/ns.html?id=GTM-5CNC9X8' style='display:none;visibility:hidden' width='0'></iframe></noscript> <!-- End Google Tag Manager (noscript) --> <a name='top'></a> <div class='container'> <!--[if lte IE 11]> <p id="whatbrowser" class="whatbrowser"> You are using an <strong>outdated</strong> browser. Please <a href="http://whatbrowser.com/" target="_blank"> upgrade your browser </a> to improve your experience. </p> <![endif]--> <header class='header-main'> <h1> <a href='https://opensource.google.com/' title='Google Open Source'> opensource.google.com </a> </h1> <a href='/#Navigation' id='NavTrigger' title='Nav Toggle Open'> <span>Menu</span> </a> <nav class='main-nav' id='Navigation'> <ul> <li class='events'> <a class='internal' href='https://opensource.google.com/events/' title='Events'> Events </a> </li> <li class='projects'> <a class='internal' href='https://opensource.google.com/projects/' title='Projects'> Projects </a> </li> <li class='programs-and-services'> <a class='internal' href='https://opensource.google/programs-and-services' title='Programs and services'> Programs and services </a> </li> <li class='docs'> <a class='internal' href='https://opensource.google/documentation/reference' title='Documentation'> Documentation </a> </li> <li class='about'> <a class='internal' href='https://opensource.google/about' title='About'> About </a> </li> <li class='blog'> <a class='internal' href='/' title='Blog'> Blog </a> </li> </ul> </nav> </header> <div class='main google-open-source'> <div class='section' id='header'><div class='widget Header' data-version='1' id='Header1'> <div class='short'></div> <section class='hero'> <div class='col-wrap'> <h2><a href='/' title='Google Open Source Blog'>Google Open Source Blog</a></h2> <p>The latest news from Google on open source releases, major projects, events, and student outreach programs.</p> </div> </section> </div></div> <section class='content'> <div class='content-outer'> <div class='region-inner main-inner'> <div class='columns'> <div class='columns-inner'> <div class='column-center-outer'> <div class='column-center-inner'> <div class='section' id='main' name='Main'><div class='widget Blog' data-version='1' id='Blog1'> <div class='blog-posts hfeed'> <div class='col-wrap'> <h2 class='archive-header'>Posts from August 2018</h2> </div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='8698702854482141883' itemprop='blogId'/> <meta content='9079527841024408101' itemprop='postId'/> <a name='9079527841024408101'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='https://opensource.googleblog.com/2018/08/introducing-tink-cryptographic-library.html'>Introducing the Tink cryptographic software library</a> </h3> <div class='post-header'> <h4 class='date-header'><span>Thursday, August 30, 2018</span></h4> </div> <div class='post-body entry-content' id='post-body-9079527841024408101' itemprop='description articleBody'> <i>Cross-posted on the <a href="https://security.googleblog.com/2018/08/introducing-tink-cryptographic-software.html">Google Security Blog</a></i><br /> <i><br /></i> At Google, many product teams use cryptographic techniques to protect user data. In cryptography, subtle mistakes can have serious consequences, and understanding how to implement cryptography correctly requires digesting decades' worth of academic literature. Needless to say, many developers don&#8217;t have time for that.<br /> <br /> To help our developers ship secure cryptographic code we&#8217;ve developed <a href="https://github.com/google/tink">Tink</a>&#8212;a multi-language, cross-platform cryptographic library. We believe in open source and want Tink to become a community project&#8212;thus Tink has been available on GitHub since the early days of the project, and it has already attracted several external contributors. At Google, Tink is already being used to secure data of many products such as AdMob, Google Pay, Google Assistant, Firebase, the Android Search App, etc. After nearly two years of development, today we&#8217;re excited to announce <a href="https://github.com/google/tink/releases/tag/v1.2.0">Tink 1.2.0</a>, the first version that supports cloud, Android, iOS, and more!<br /> <br /> Tink aims to provide cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse. Tink is built on top of existing libraries such as BoringSSL and Java Cryptography Architecture, but includes countermeasures to many weaknesses in these libraries, which were discovered by <a href="https://github.com/google/wycheproof">Project Wycheproof</a>, another project from our team.<br /> <br /> With Tink, many common cryptographic operations such as data encryption, digital signatures, etc. can be done with only a few lines of code. Here is an example of encrypting and decrypting with our <a href="https://github.com/google/tink/blob/master/docs/PRIMITIVES.md#authenticated-encryption-with-associated-data">AEAD</a>&nbsp;interface in Java:<br /> <pre class="prettyprint"> import com.google.crypto.tink.Aead; import com.google.crypto.tink.KeysetHandle; import com.google.crypto.tink.aead.AeadFactory; import com.google.crypto.tink.aead.AeadKeyTemplates; // 1. Generate the key material. KeysetHandle keysetHandle = KeysetHandle.generateNew( AeadKeyTemplates.AES256_EAX); // 2. Get the primitive. Aead aead = AeadFactory.getPrimitive(keysetHandle); // 3. Use the primitive. byte[] plaintext = ...; byte[] additionalData = ...; byte[] ciphertext = aead.encrypt(plaintext, additionalData); </pre> Tink aims to eliminate as many potential misuses as possible. For example, if the underlying encryption mode requires nonces and nonce reuse makes it insecure, then Tink does not allow the user to pass nonces. Interfaces have security guarantees that must be satisfied by each primitive implementing the interface. This may exclude some encryption modes. Rather than adding them to existing interfaces and weakening the guarantees of the interface, it is possible to add new interfaces and describe the security guarantees appropriately.<br /> <br /> We&#8217;re cryptographers and security engineers working to improve Google&#8217;s product security, so we built Tink to make our job easier. Tink shows the claimed security properties (e.g., safe against chosen-ciphertext attacks) right in the interfaces, allowing security auditors and automated tools to quickly discover usages where the security guarantees don&#8217;t match the security requirements. Tink also isolates APIs for potentially dangerous operations (e.g., loading cleartext keys from disk), which allows discovering, restricting, monitoring and logging their usage.<br /> <br /> Tink provides support for key management, including key rotation and phasing out deprecated ciphers. For example, if a cryptographic primitive is found to be broken, you can switch to a different primitive by rotating keys, without changing or recompiling code.<br /> <br /> Tink is also extensible by design: it is easy to add a custom cryptographic scheme or an in-house key management system so that it works seamlessly with other parts of Tink. No part of Tink is hard to replace or remove. All components are composable, and can be selected and assembled in various combinations. For example, if you need only digital signatures, you can exclude symmetric key encryption components to minimize code size in your application.<br /> <br /> To get started, please check out our HOW-TO for <a href="https://github.com/google/tink/blob/master/docs/JAVA-HOWTO.md">Java</a>, <a href="https://github.com/google/tink/blob/master/docs/CPP-HOWTO.md">C++</a> and <a href="https://github.com/google/tink/blob/master/docs/OBJC-HOWTO.md">Obj-C</a>. If you'd like to talk to the developers or get notified about project updates, you may want to subscribe to our <a href="https://groups.google.com/forum/#!forum/tink-users">mailing list</a>. To join, simply send an empty email to <a href="mailto:tink-users+subscribe@googlegroups.com">tink-users+subscribe@googlegroups.com</a>. You can also post your questions to StackOverflow, just remember to tag them with <a href="https://stackoverflow.com/questions/tagged/tink">tink</a>.<br /> <br /> We&#8217;re excited to share this with the community, and welcome your feedback!<br /> <br /> <i>By Thai Duong, Information Security Engineer, on behalf of Tink team</i> <div style='clear: both;'></div> </div> </div> </div> <div class='post-footer'> </div> </div></div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMhE8INtZ9nb7fR2Rz9BfpRK1f26NMv6DO_7YPjf_PRpD8BtQeTGDjDN8dXtZtpMDOP9tsFxc2QLWvdjNj10f5Ng3fIFj5szRWonrPekvxD6kdA2GaPNRtnlfhF_1wh9J8qDUqR3BFpZ8/s320/GCI+-+Vertical+-+Gray+Text+-+White+BG.png' itemprop='image_url'/> <meta content='8698702854482141883' itemprop='blogId'/> <meta content='1745643586016618989' itemprop='postId'/> <a name='1745643586016618989'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='https://opensource.googleblog.com/2018/08/announcing-google-code-in-2018.html'>Announcing Google Code-in 2018: nine is just fine!</a> </h3> <div class='post-header'> <h4 class='date-header'><span>Wednesday, August 29, 2018</span></h4> </div> <div class='post-body entry-content' id='post-body-1745643586016618989' itemprop='description articleBody'> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMhE8INtZ9nb7fR2Rz9BfpRK1f26NMv6DO_7YPjf_PRpD8BtQeTGDjDN8dXtZtpMDOP9tsFxc2QLWvdjNj10f5Ng3fIFj5szRWonrPekvxD6kdA2GaPNRtnlfhF_1wh9J8qDUqR3BFpZ8/s1600/GCI+-+Vertical+-+Gray+Text+-+White+BG.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="1393" data-original-width="1600" height="278" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMhE8INtZ9nb7fR2Rz9BfpRK1f26NMv6DO_7YPjf_PRpD8BtQeTGDjDN8dXtZtpMDOP9tsFxc2QLWvdjNj10f5Ng3fIFj5szRWonrPekvxD6kdA2GaPNRtnlfhF_1wh9J8qDUqR3BFpZ8/s320/GCI+-+Vertical+-+Gray+Text+-+White+BG.png" width="320" /></a></div> We are excited to announce the 9th consecutive year of the <a href="https://g.co/gci">Google Code-in</a> (GCI) contest! Students ages 13 through 17 from around the world can learn about open source development by working on real open source projects, with mentorship from active developers. GCI begins on <a href="https://developers.google.com/open-source/gci/timeline">Tuesday, October 23, 2018</a> and runs for seven weeks, ending Wednesday, December 12, 2018.<br /> <br /> Google Code-in is unique because, not only do the students choose what they want to work on from the 2,500+ tasks created by open source organizations, but they have mentors available to help answer their questions as they work on each of their tasks.<br /> <br /> Getting started in open source software can be a daunting task for a developer of any age. <i>What organization should I work with? How do I get started? Does the organization want my help? Am I too inexperienced?</i><br /> <br /> The beauty of GCI is that participating open source organizations realize teens are often first time contributors, so the volunteer mentors come prepared with the patience and the experience to help these newcomers become part of the open source community.<br /> <br /> Open source communities thrive when there is a steady flow of new contributors who bring new perspectives, ideas and enthusiasm. Over the last 8 years, GCI open source organizations have helped 8,108 students from 107 countries make meaningful contributions. Many of these students are still participating in open source communities years later. Dozens have gone on to become <a href="https://g.co/gsoc">Google Summer of Code</a> (GSoC) students and even mentor other students.<br /> <br /> The tasks that contest participants will complete vary in skill set and level, including beginner tasks any student can take on, such as &#8220;setup your development environment.&#8221; With tasks in five different categories, there&#8217;s something to fit almost any student&#8217;s skills:<br /> <ul> <li>Code: writing or refactoring</li> <li>Documentation/Training: creating/editing documents and helping others learn more</li> <li>Outreach/Research: community management, marketing, or studying problems and recommending solutions</li> <li>Quality Assurance: testing and ensuring code is of high quality</li> <li>Design: graphic design or user interface design</li> </ul> Open source organizations can apply to participate as mentoring organizations for in Google Code-in starting on Thursday, September 6, 2018. <b>Google Code-in starts for students October 23rd!</b><br /> <br /> Visit the contest site <a href="https://g.co/gci">g.co/gci</a> to learn more about the contest and find flyers, slide decks, timelines, and more.<br /> <br /> <i>By Stephanie Taylor, Google Open Source</i> <div style='clear: both;'></div> </div> </div> </div> <div class='post-footer'> </div> </div></div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtxEZaMNjviSS6a8ghVUabs8Ow-Z2dYpc5eZIFp0rckgBHXMDIUK6r3TjowBioiA9KZ_ErPvahhKs1mbSZnsdzSMuduPkSMHEzOnLllxP1fkZCxnMHG_lpOwUb_JES_uvUVhPhXoApucQ/s320/GSoC+-+Vertical+Wide+-+Gray+Text+-+White+BG.png' itemprop='image_url'/> <meta content='8698702854482141883' itemprop='blogId'/> <meta content='1152764645892258594' itemprop='postId'/> <a name='1152764645892258594'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='https://opensource.googleblog.com/2018/08/thats-a-wrap-gsoc-2018.html'>That&#8217;s a wrap for Google Summer of Code 2018</a> </h3> <div class='post-header'> <h4 class='date-header'><span>Wednesday, August 22, 2018</span></h4> </div> <div class='post-body entry-content' id='post-body-1152764645892258594' itemprop='description articleBody'> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtxEZaMNjviSS6a8ghVUabs8Ow-Z2dYpc5eZIFp0rckgBHXMDIUK6r3TjowBioiA9KZ_ErPvahhKs1mbSZnsdzSMuduPkSMHEzOnLllxP1fkZCxnMHG_lpOwUb_JES_uvUVhPhXoApucQ/s1600/GSoC+-+Vertical+Wide+-+Gray+Text+-+White+BG.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="951" data-original-width="1600" height="190" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtxEZaMNjviSS6a8ghVUabs8Ow-Z2dYpc5eZIFp0rckgBHXMDIUK6r3TjowBioiA9KZ_ErPvahhKs1mbSZnsdzSMuduPkSMHEzOnLllxP1fkZCxnMHG_lpOwUb_JES_uvUVhPhXoApucQ/s320/GSoC+-+Vertical+Wide+-+Gray+Text+-+White+BG.png" width="320" /></a></div> We are pleased to announce that 1,072 students from 59 countries have successfully completed the 2018 <a href="https://g.co/gsoc">Google Summer of Code</a> (GSoC). Congratulations to all of our students and mentors who made this our biggest and best Google Summer of Code yet.<br /> <br /> Over the past 12 weeks, GSoC students have worked diligently with <a href="https://summerofcode.withgoogle.com/organizations/">212 open source organizations</a> and over <a href="https://opensource.googleblog.com/2018/08/magnificent-mentors-of-gsoc.html">2,100 mentors</a> from all around the world, learning to work with distributed teams and developing complex pieces of code. Student projects are now public &#8211; take a closer look at&nbsp;<a href="https://summerofcode.withgoogle.com/projects/">their work</a>.<br /> <br /> Open source communities need new ideas to keep projects thriving and evolving; GSoC students bring fresh perspectives while helping organizations enhance, extend, and refine their codebases. This is not the end of the road for GSoC students! Many will go on to become mentors in future years and many more will become long-term committers.<br /> <br /> And finally, a big thank you to the mentors and organization administrators who make GSoC possible. Their dedication to welcoming new student contributors into their communities is awesome and inspiring. Thank you all!<br /> <br /> <i>By Mary Radomile, Google Open Source</i> <div style='clear: both;'></div> </div> </div> </div> <div class='post-footer'> </div> </div></div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCUnAhiygsrVIyC-Mpl_8ix4uGE-XFzkEHS7VAiql5LzVpJuEuV_Wg2hw2Muf5aBjS25LlFG0TM31p484uy_aRm6ULksmGj5dGumDi8xLX732u5j1xRNEtxCjHj6BTCTqVztxTuXfwRFQ/s320/zurihac+logo.png' itemprop='image_url'/> <meta content='8698702854482141883' itemprop='blogId'/> <meta content='949472823021474361' itemprop='postId'/> <a name='949472823021474361'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='https://opensource.googleblog.com/2018/08/zurihac-2018-haskell-hackathon-in.html'>ZuriHac 2018: Haskell hackathon in Rapperswil</a> </h3> <div class='post-header'> <h4 class='date-header'><span>Friday, August 17, 2018</span></h4> </div> <div class='post-body entry-content' id='post-body-949472823021474361' itemprop='description articleBody'> <i>Google Open Source recently co-sponsored a three-day hackathon for Haskell, an open source functional programming language. Ivan Krišto from Google&#8217;s Zürich office talks more about the event below.</i><br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCUnAhiygsrVIyC-Mpl_8ix4uGE-XFzkEHS7VAiql5LzVpJuEuV_Wg2hw2Muf5aBjS25LlFG0TM31p484uy_aRm6ULksmGj5dGumDi8xLX732u5j1xRNEtxCjHj6BTCTqVztxTuXfwRFQ/s1600/zurihac+logo.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="400" data-original-width="774" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCUnAhiygsrVIyC-Mpl_8ix4uGE-XFzkEHS7VAiql5LzVpJuEuV_Wg2hw2Muf5aBjS25LlFG0TM31p484uy_aRm6ULksmGj5dGumDi8xLX732u5j1xRNEtxCjHj6BTCTqVztxTuXfwRFQ/s320/zurihac+logo.png" width="320" /></a></div> Over the weekend of June 9th, Rapperswil, Switzerland became a home for 300 Haskellers. <a href="https://www.hsr.ch/">Hochschule für Technik Rapperswil</a> hosted the seventh annual <a href="https://zurihac.info/">ZuriHac</a>, the biggest Haskell Hackathon in Europe. ZuriHac is a free, international coding festival with the goal to expand our community and to build and improve Haskell libraries, tools and infrastructure.<br /> <br /> Participants could choose to hack all day long, attend the Haskell beginners course led by <a href="https://argumatronic.com/">Julie Moronuki</a>, join the <a href="https://www.haskell.org/ghc/">Glasgow Haskell Compiler</a> (GHC) DevOps track organized by GHC contributors with the goal to bring in new contributors, listen to the Haskell flavoured talks, or socialize and swim in the lake. The event was colocated with <a href="https://isocpp.org/std/the-committee">C++ standardization committee</a> meetings which offered a unique opportunity for sharing ideas between the two communities.<br /> <br /> Here is a short summary of featured talks at ZuriHac.<br /> <ul> <li><a href="https://twitter.com/nikivazou">Niki Vazou</a> presented <a href="https://youtu.be/SmRo7q_6oG8?list=PLOvRW_utVPVlMaey1LnM1FWGnJwztEz5O">Liquid Haskell: Refinement Types for Haskell</a>, a way to enforce critical properties of functions at the type level at compile time.&nbsp;</li> <li><a href="https://twitter.com/smdiehl">Stephen Diehl</a> talked about the state of LLVM bindings for Haskell in <a href="https://youtu.be/wn-xW3g8jXY?list=PLOvRW_utVPVlMaey1LnM1FWGnJwztEz5O">Building compilers with llvm-hs</a>.&nbsp;</li> <li><a href="https://github.com/ekmett">Edward Kmett</a> presented ideas for improving the Haskell combinators: <a href="https://youtu.be/PA1Fc7DNKtA?list=PLOvRW_utVPVlMaey1LnM1FWGnJwztEz5O">Combinators Revisited</a>.&nbsp;</li> <li><a href="https://github.com/Gabriel439">Gabriel Gonzalez</a> presented an approach to parallelize finite state machines and how to deal with their performance bottlenecks in <a href="https://youtu.be/b4bb8EP_pIE?list=PLOvRW_utVPVlMaey1LnM1FWGnJwztEz5O">Fast and parallel state machines</a>.&nbsp;</li> <li><a href="https://www.joachim-breitner.de/">Joachim Breitner</a> gave an overview of state-of-the-art inspection testing: <a href="https://youtu.be/NYjk1kaYIgk?list=PLOvRW_utVPVlMaey1LnM1FWGnJwztEz5O">A promise checked is a promise kept: Inspection Testing</a>.</li> <li><a href="https://twitter.com/TacticalGrace">Manuel Chakravarty</a> talked about GHC's development process: <a href="https://youtu.be/dxFvqsPdu9U?list=PLOvRW_utVPVlMaey1LnM1FWGnJwztEz5O">Continuous Integration &amp; Testing for GHC</a>.</li> </ul> The event concluded with a presentation of the results of the three day hackathon: <a href="https://youtu.be/jyUX6F5ixCg?list=PLOvRW_utVPVlMaey1LnM1FWGnJwztEz5O">project presentations</a>.<br /> <br /> <div class="intrinsic-container intrinsic-container-16x9"> <iframe allowfullscreen="allowfullscreen" src="https://www.youtube.com/embed/ExJzgrEHlDI?rel=0"></iframe></div> <div style="text-align: center;"> <i>Video by Hochschule für Technik Rapperswil.</i></div> <br /> Once again, we broke the attendance record! We&#8217;re already preparing for <a href="https://zfoh.ch/zurihac2019/">ZuriHac 2019</a> and hope to keep up this amazing growth. See you next year!<br /> <br /> <i>By Ivan Krišto, Software Engineer</i> <div style='clear: both;'></div> </div> </div> </div> <div class='post-footer'> </div> </div></div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgukLSYJgZwFiUTTXVCsd6ILWmbgztedBJz9g2PeoAXn_d_QjBV4regFDbNYZsKVr9Nykl2zwpZUo0yzQa5HA4XhY60GmPUxg-jKFxwLyt6BVZ3mg17nCd7TqQ3X75zp1hx00yEH6f_am8/s320/Google+Open+Source+Peer+Bonus+-+Vertical+-+White+BG.png' itemprop='image_url'/> <meta content='8698702854482141883' itemprop='blogId'/> <meta content='7269449046219300395' itemprop='postId'/> <a name='7269449046219300395'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='https://opensource.googleblog.com/2018/08/congratulations-to-open-source-peer-bonus-winners.html'>Congratulations to the latest Google Open Source Peer Bonus winners</a> </h3> <div class='post-header'> <h4 class='date-header'><span>Wednesday, August 15, 2018</span></h4> </div> <div class='post-body entry-content' id='post-body-7269449046219300395' itemprop='description articleBody'> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgukLSYJgZwFiUTTXVCsd6ILWmbgztedBJz9g2PeoAXn_d_QjBV4regFDbNYZsKVr9Nykl2zwpZUo0yzQa5HA4XhY60GmPUxg-jKFxwLyt6BVZ3mg17nCd7TqQ3X75zp1hx00yEH6f_am8/s1600/Google+Open+Source+Peer+Bonus+-+Vertical+-+White+BG.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="825" data-original-width="1600" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgukLSYJgZwFiUTTXVCsd6ILWmbgztedBJz9g2PeoAXn_d_QjBV4regFDbNYZsKVr9Nykl2zwpZUo0yzQa5HA4XhY60GmPUxg-jKFxwLyt6BVZ3mg17nCd7TqQ3X75zp1hx00yEH6f_am8/s320/Google+Open+Source+Peer+Bonus+-+Vertical+-+White+BG.png" width="320" /></a></div> We are pleased to announce the latest round of <a href="https://opensource.google.com/docs/growing/peer-bonus/">Google Open Source Peer Bonus</a> winners and the projects they support.<br /> <br /> Open source software is a cornerstone of software development inside and outside of Google, and the Google Open Source Peer Bonus program is one way we thank the people who make our work possible. Twice a year we invite Googlers to nominate external contributors to be rewarded for their contribution to open source projects.<br /> <br /> This time we have a truly international team of recipients from Australia, Brazil, Canada, Germany, India, Italy, Ireland, France, Japan, Netherlands, Russia, Singapore, Switzerland, Sweden, UK and USA. You can learn about previous recipients in <a href="https://opensource.googleblog.com/search/label/peer%20bonus%20program">these blog posts</a>.<br /> <br /> Projects range from Linux distributions and version control systems to monitoring and testing software. Some are part of the backbone of our industry, others are critical dependencies of specific products and services we offer. All of them are important to us!<br /> <br /> Listed below are the individuals who gave us permission to thank them publicly:<br /> <br /> <table class="pb_table"> <thead> <tr> <td>Name </td> <td>Project </td> <td>Name </td> <td>Project </td> </tr> </thead> <tbody> <tr><td>Sultan Alsawaf</td><td><a href="https://source.android.com/devices/architecture/kernel/android-common">Android Kernel</a></td><td>Ravi Santosh Gudimetla</td><td><a href="https://github.com/kubernetes/kubernetes">Kubernetes</a></td></tr> <tr><td>Allan McRae</td><td><a href="https://www.archlinux.org/">Arch Linux</a></td><td>Steve Kuznetsov</td><td><a href="https://github.com/kubernetes/kubernetes">Kubernetes</a></td></tr> <tr><td>Seth Pollack</td><td><a href="https://github.com/kubernetes-sigs/aws-encryption-provider">aws-encryption-provider</a></td><td>Hisham Muhammad</td><td><a href="https://luarocks.org/">LuaRocks</a></td></tr> <tr><td>George Gensure</td><td><a href="https://github.com/bazelbuild/bazel-buildfarm">Bazel Buildfarm</a></td><td>Yutaka Matsubara</td><td><a href="https://github.com/mopemope/meinheld">meinheld</a></td></tr> <tr><td>Omar Cornut</td><td><a href="https://github.com/ocornut/imgui">Dear ImGui</a></td><td>Pulkit Goyal</td><td><a href="https://www.mercurial-scm.org/">Mercurial</a></td></tr> <tr><td>Alessandro Arzilli</td><td><a href="https://github.com/derekparker/delve">Delve</a></td><td>Yuya Nishihara</td><td><a href="https://www.mercurial-scm.org/">Mercurial</a></td></tr> <tr><td>Matt Klein</td><td><a href="https://github.com/envoyproxy/envoy">Envoy</a></td><td>Adam Mummery-Smith</td><td><a href="https://github.com/SpongePowered/Mixin">Mixin</a></td></tr> <tr><td>Ivan Grokhotkov</td><td><a href="https://github.com/esp8266/Arduino">ESP8266 core for Arduino</a></td><td>Arnout Engelen</td><td><a href="http://notion.sourceforge.net/">Notion</a></td></tr> <tr><td>Esther Onfroy</td><td><a href="https://github.com/Exodus-Privacy/exodus">Exodus Privacy</a></td><td>Brian Brazil</td><td><a href="https://github.com/prometheus/prometheus">Prometheus</a></td></tr> <tr><td>Yao Li</td><td><a href="https://github.com/lastland/scala-forklift">Forklift</a></td><td>Bruno Oliveira</td><td><a href="https://docs.pytest.org/en/latest/">pytest</a></td></tr> <tr><td>Warner Losh</td><td><a href="https://www.freebsd.org/">FreeBSD</a></td><td>James Friedman</td><td><a href="https://github.com/jamesmfriedman/rmwc">RMWC</a></td></tr> <tr><td>Elijah Newren</td><td><a href="https://git-scm.com/">Git</a></td><td>Steve Klabnik</td><td><a href="https://github.com/rust-lang/book">Rust Book</a></td></tr> <tr><td>Gábor Szeder</td><td><a href="https://git-scm.com/">Git</a></td><td>Jack Lukic</td><td><a href="https://semantic-ui.com/">Semantic UI</a></td></tr> <tr><td>Alvaro Viebrantz</td><td><a href="https://github.com/GoogleCloudPlatform/google-cloud-iot-arduino">google-cloud-iot-arduino</a></td><td>Vidar Holen</td><td><a href="https://github.com/koalaman/shellcheck">ShellCheck</a></td></tr> <tr><td>Richard Musiol</td><td><a href="https://github.com/gopherjs/gopherjs">GopherJS</a>, <a href="https://github.com/golang/go">go-wasm</a></td><td>Ivan Popelyshev</td><td><a href="https://skia.org/">Skia graphics in Chrome</a></td></tr> <tr><td>Tobias Furuholm</td><td><a href="https://github.com/grafeas/grafeas">Grafeas</a></td><td>Spencer Gibb</td><td><a href="https://github.com/spring-cloud/">Spring Cloud</a></td></tr> <tr><td>David Pursehouse</td><td><a href="https://github.com/eclipse/jgit">JGit</a></td><td>Daniel Alm</td><td><a href="https://github.com/grpc/grpc-swift">Swift gRPC</a></td></tr> <tr><td>Brian Granger</td><td><a href="https://github.com/jupyter/notebook">Jupyter</a></td><td>Yong Tang</td><td><a href="https://github.com/tensorflow/tensorflow">TensorFlow</a></td></tr> <tr><td>Rodrigo Menezes</td><td><a href="https://github.com/kubernetes/kops">kops</a></td><td>Jason Zaman</td><td><a href="https://github.com/tensorflow/tensorflow">TensorFlow</a>, <a href="https://www.gentoo.org/">Gentoo</a>, <a href="https://github.com/SELinuxProject/selinux">SELinux</a></td></tr> <tr><td>Rohith Jayawardene</td><td><a href="https://github.com/kubernetes/kops">kops</a></td><td>Kai Sasaki</td><td><a href="https://github.com/tensorflow/tfjs">TensorFlow.js</a></td></tr> <tr><td>Kam Kasravi</td><td><a href="https://github.com/kubeflow/kubeflow">Kubeflow</a></td><td>Manraj Grover</td><td><a href="https://github.com/tensorflow/tfjs">TensorFlow.js</a></td></tr> <tr><td>Pete MacKinnon</td><td><a href="https://github.com/kubeflow/kubeflow">Kubeflow</a></td><td>Stefan Weil</td><td><a href="https://github.com/tesseract-ocr/tesseract">Tesseract</a></td></tr> <tr><td>Christoph Blecker</td><td><a href="https://github.com/kubernetes/kubernetes">Kubernetes</a></td><td>Sumana Harihareswara</td><td><a href="https://github.com/pypa/warehouse">Warehouse (PyPI)</a></td></tr> <tr><td>Davanum Srinivas</td><td><a href="https://github.com/kubernetes/kubernetes">Kubernetes</a></td><td>Jia Li</td><td><a href="https://github.com/angular/zone.js/">zone.js</a></td></tr> </tbody> </table> <br /> Once again we would like to express our gratitude and appreciation to current and former recipients for their hard work, time and devotion to open source. Without you these projects wouldn&#8217;t thrive!<br /> <br /> We look forward to your ongoing contributions and can&#8217;t wait to recognize even more contributors for their work in 2019.<br /> <br /> <i>By Maria Tabak, Google Open Source</i> <div style='clear: both;'></div> </div> </div> </div> <div class='post-footer'> </div> </div></div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='8698702854482141883' itemprop='blogId'/> <meta content='1851032014284705751' itemprop='postId'/> <a name='1851032014284705751'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='https://opensource.googleblog.com/2018/08/how-we-brought-latest-python-to-app-engine.html'>How we brought the latest version of Python to App Engine and Cloud Functions</a> </h3> <div class='post-header'> <h4 class='date-header'><span>Monday, August 13, 2018</span></h4> </div> <div class='post-body entry-content' id='post-body-1851032014284705751' itemprop='description articleBody'> At Cloud Next 2018, we added Python 3.7 support to <a href="https://cloud.google.com/functions/docs/">Cloud Functions</a> and now <a href="https://cloud.google.com/blog/products/gcp/introducing-app-engine-second-generation-runtimes-and-python-3-7">we&#8217;ve announced</a> Python 3.7 support for the <a href="https://cloud.google.com/appengine/docs/standard/python3">App Engine standard environment</a>. These new runtimes allow you to write Python functions and apps using the latest version of Python and the rich ecosystem of packages available on <a href="https://pypi.org/">Python Packaging Index (PyPI)</a>.<br /> <br /> This new runtime marks a significant update to App Engine and was enabled by new open source software that we recently released: <a href="https://cloudplatform.googleblog.com/2018/05/Open-sourcing-gVisor-a-sandboxed-container-runtime.html">gVisor</a> and <a href="https://github.com/GoogleCloudPlatform/runtimes-common/tree/master/ftl">FTL</a>.<br /> <h2> Python, straight from the source</h2> Running Python 3.7 on App Engine and Cloud Functions required us to fundamentally rethink our infrastructure. Traditionally, meeting Google Cloud&#8217;s security requirements meant that we had to run a modified version of the Python interpreter. However, using a modified interpreter constrained some language features and only allowed us to support a limited set of whitelisted Python libraries.<br /> <br /> Thanks to gVisor, a container sandbox that provides improved security and process isolation, we can now run the unmodified Python 3.7.0 interpreter. We&#8217;ve done extensive testing to make sure Python 3.7 is compatible with gVisor. As part of our compatibility testing, we run Python&#8217;s full suite of language tests, and tests for Python packages that are popular on PyPI. We&#8217;re committed to ensuring that everything you&#8217;ve come to know and love about Python is supported on our platform.<br /> <h2> Seamless deployments</h2> Most importantly, this change in our infrastructure makes it easier to take advantage of Python&#8217;s vast ecosystem. As a developer, you just add project dependencies to a <span style="font-family: Courier New, Courier, monospace;">requirements.txt</span> file and deploy.<br /> <br /> During deployment, FTL, a tool for building containers, fetches dependencies listed in your <span style="font-family: Courier New, Courier, monospace;">requirements.txt</span> file and installs them alongside your app or function. FTL also includes a short-lived dependency cache, which speeds up repeated deployments if no changes are detected in your <span style="font-family: Courier New, Courier, monospace;">requirements.txt</span> file. This is particularly useful if you find just need to re-deploy because you found a typo.<br /> <h2> Keeping up with the Pythonistas</h2> In making these changes, we also decided to expand the <a href="https://cloud.google.com/appengine/docs/standard/python3/reference/system-packages">list of system packages</a> that are included with each runtime&#8217;s Ubuntu 18.04 distribution. We think that will make life just a little bit easier for developers working with the latest release of Python.<br /> <br /> Looking forward, we&#8217;re excited about how these changes will allow us to keep up with the Python community&#8217;s progress as they release new versions and libraries. Please let us know what you think and if you run into any challenges.<br /> <br /> You can learn more about how to get started with it on <a href="https://cloud.google.com/appengine/docs/standard/python3/">App Engine</a> and <a href="https://cloud.google.com/functions/docs/">Cloud Functions</a> in our documentation. We can&#8217;t wait to see what you build with Python 3.7.<br /> <br /> <i>By Stewart Reichling, Product Manager</i> <div style='clear: both;'></div> </div> </div> </div> <div class='post-footer'> </div> </div></div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikV3ZhAdT1HeA-teK8v7S6a3TU9PzbEc-sA3hxGGBXsyOidr_0SUgzN9YmBzWV4-O1_2UtVUYSgd-T0HNh2hts-HEonp8V2m4LWZtpw_t9VvvzlVpnH35TPr0l649LaDwAsStGRvRG0u0/s200/openmetrics.png' itemprop='image_url'/> <meta content='8698702854482141883' itemprop='blogId'/> <meta content='5074392695183931467' itemprop='postId'/> <a name='5074392695183931467'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='https://opensource.googleblog.com/2018/08/openmetrics-project-accepted-into-cncf.html'>OpenMetrics project accepted into CNCF Sandbox</a> </h3> <div class='post-header'> <h4 class='date-header'><span>Friday, August 10, 2018</span></h4> </div> <div class='post-body entry-content' id='post-body-5074392695183931467' itemprop='description articleBody'> For the past several months, engineers from Google Cloud, <a href="https://prometheus.io/">Prometheus</a>, and other vendors have been aligning on <a href="http://openmetrics.io/">OpenMetrics</a>, a specification for metrics exposition. Today, the project was formally announced and accepted into the <a href="https://github.com/cncf/toc/blob/master/process/sandbox.md">CNCF Sandbox</a>, and we&#8217;re currently working on ways to support OpenMetrics in&nbsp;<a href="https://opencensus.io/">OpenCensus</a>, a set of uniform tracing and stats libraries that work with multiple vendors&#8217; services. This multi-vendor approach works to put architectural choices in the hands of developers.<br /> <table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody> <tr><td style="text-align: center; vertical-align: middle;"><img border="0" data-original-height="200" data-original-width="200" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikV3ZhAdT1HeA-teK8v7S6a3TU9PzbEc-sA3hxGGBXsyOidr_0SUgzN9YmBzWV4-O1_2UtVUYSgd-T0HNh2hts-HEonp8V2m4LWZtpw_t9VvvzlVpnH35TPr0l649LaDwAsStGRvRG0u0/s200/openmetrics.png" width="150" /> <span style="font-size: 48px; line-height: 150px; margin: 0 0.5em; vertical-align: top;">+</span> <img border="0" data-original-height="200" data-original-width="200" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioJ_mSwfIzte8KhmoGe10Ia6-flx9NDI2gVJFa32jY42t1Beti0qyoUnlAKO3hn8CiZ7HrNUfhIfbFnX6k625wIWBdP0jx9os1vINpNZec3NEBd2rRZUBUO0qEiWm7VpxQuituFkk5_Ws/s1600/opencensus.png" width="150" /></td></tr> </tbody></table> OpenMetrics stems from the stats formats used inside of Prometheus and Google&#8217;s Monarch time-series infrastructure, which underpins both Stackdriver and internal monitoring applications. As such, it is designed to be immediately familiar to developers and capable of operating at extreme scale. With additional contributions and review from AppOptics, Cortex, Datadog, InfluxData, Sysdig, and Uber, OpenMetrics has begun the cross-industry collaboration necessary to drive adoption of a new specification.<br /> <br /> OpenCensus provides automatic instrumentation, APIs, and exporters for stats and distributed traces across C++, Java, Go, Node.js, Python, PHP, Ruby, and .Net. Each OpenCensus library allows developers to automatically capture distributed traces and key RPC-related statistics from their applications, add custom data, and export telemetry to their back-end of choice. Google has been a key collaborator in defining the OpenMetrics specification, and we&#8217;re now focusing on how to best implement this inside of OpenCensus.<br /> <br /> &#8220;Google has a history of innovation in the metric monitoring space, from its early success with Borgmon, which has been continued in Monarch and Stackdriver. OpenMetrics embodies our understanding of what users need for simple, reliable and scalable monitoring, and shows our commitment to offering standards-based solutions,&#8221; said Sumeer Bhola, Lead Engineer on Monarch and Stackdriver at Google.<br /> <br /> For more information about OpenMetrics, please visit <a href="http://openmetrics.io/">openmetrics.io</a>. For more information about OpenCensus and how you can quickly enable trace and metrics collection from your application, please visit <a href="https://opencensus.io/">opencensus.io</a>.<br /> <br /> <i>By Morgan McLean, Product Manager for OpenCensus and Stackdriver APM</i> <div style='clear: both;'></div> </div> </div> </div> <div class='post-footer'> </div> </div></div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_m_9SfrriybiztAqBkfe0m9Tq1MAAju0-YOnHLMe4IeMWGwtZrGiuzWAQdSIsW-MksSJDIMAGXxLOnR1ieKPcLDDuoHmrp4hNM0d6-VxDS31dEtK4JXfgFqI68NUByvpUWLhmhiHAFso/s200/ZvmtaSXW_400x400.jpg' itemprop='image_url'/> <meta content='8698702854482141883' itemprop='blogId'/> <meta content='3527499394719597524' itemprop='postId'/> <a name='3527499394719597524'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='https://opensource.googleblog.com/2018/08/introducing-new-lead-for-android.html'>Introducing the new lead for Android Open Source Project</a> </h3> <div class='post-header'> <h4 class='date-header'><span>Wednesday, August 8, 2018</span></h4> </div> <div class='post-body entry-content' id='post-body-3527499394719597524' itemprop='description articleBody'> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_m_9SfrriybiztAqBkfe0m9Tq1MAAju0-YOnHLMe4IeMWGwtZrGiuzWAQdSIsW-MksSJDIMAGXxLOnR1ieKPcLDDuoHmrp4hNM0d6-VxDS31dEtK4JXfgFqI68NUByvpUWLhmhiHAFso/s1600/ZvmtaSXW_400x400.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="400" data-original-width="400" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_m_9SfrriybiztAqBkfe0m9Tq1MAAju0-YOnHLMe4IeMWGwtZrGiuzWAQdSIsW-MksSJDIMAGXxLOnR1ieKPcLDDuoHmrp4hNM0d6-VxDS31dEtK4JXfgFqI68NUByvpUWLhmhiHAFso/s200/ZvmtaSXW_400x400.jpg" width="200" /></a></div> This week began with the <a href="https://blog.google/products/android/introducing-android-9-pie/">announcement of Android 9 Pie</a> and, as usual, the subsequent <a href="https://groups.google.com/forum/#!topic/android-building/PeF_PdaeB0U">upstreaming of code</a> to the <a href="https://source.android.com/">Android Open Source Project</a> (AOSP). But the release of Android 9 isn&#8217;t the only important Android news!<br /> <br /> Tucked away in the announcement to the Android Building mailing list was this note:<br /> <br /> <i>&#8220;I also wanted to take a moment to introduce myself as the new Tech Lead / Manager for AOSP. My name is Jeff Bailey, and I&#8217;ve been involved in the Open Source community for more than two decades. Since I joined the Android team a few months ago, I&#8217;ve been learning how we do things and getting an understanding of how we could work better with the community. I&#8217;d love to hear from you: <a href="https://twitter.com/JeffBaileyAOSP">@JeffBaileyAOSP</a> on Twitter or <a href="mailto:jeffbailey+aosp@google.com">jeffbailey+aosp@google.com</a>. Be well!&#8221;</i><br /> <br /> As Jeff notes in his introduction, he has a history in free and open source software (FOSS). He&#8217;s been an avid user, contributor, and maintainer since before the <a href="https://en.wikipedia.org/wiki/The_Open_Source_Definition">Open Source Definition</a> was inked!<br /> <br /> Jeff co-founded <a href="https://savannah.gnu.org/">Savannah</a>, where <a href="https://www.gnu.org/">GNU</a> software is developed and distributed, spent 15 years working on <a href="https://www.debian.org/">Debian</a>, and has been an <a href="https://ubuntu.com/">Ubuntu</a> core developer. Further, he spent some time on the Google Open Source team and was involved in <a href="https://opensource.googleblog.com/2008/10/first-android-patch-accepted.html">open sourcing Android back in 2008</a>.<br /> <br /> Open source projects, even those which originate inside of companies, are powered by the community of users and contributors that surround them. And those communities thrive when they have stewards who are steeped in the traditions of free and open source software. We&#8217;re excited for AOSP as Jeff takes the reins. He brings both technical and cultural skills to the table, and he&#8217;s been involved with the project since the beginning!<br /> <br /> Suffice it to say, AOSP is in good hands. We welcome Jeff to his new role and, as he said in his introduction, he&#8217;d love to hear from the community: you can reach Jeff on <a href="https://twitter.com/JeffBaileyAOSP">Twitter</a> and via <a href="mailto:jeffbailey+aosp@google.com">email</a>.<br /> <br /> <i>By Josh Simmons, Google Open Source</i> <div style='clear: both;'></div> </div> </div> </div> <div class='post-footer'> </div> </div></div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggrFw8R5ypI1e7ryvFKodqrUo-itOn0hPItl8h0cp7QNvMLBjC_DDvEEU3OIEO9k9grr_VQT9hHTl2nmLvgoM-asYGM5qw2Y6NXwYIXqqoJImr7ZmkLC0THfEIVuYdqwya2IhYD-msadA/s200/GSoC+-+Vertical+Narrow+-+Gray+Text+-+White+BG.png' itemprop='image_url'/> <meta content='8698702854482141883' itemprop='blogId'/> <meta content='2088581913953489546' itemprop='postId'/> <a name='2088581913953489546'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='https://opensource.googleblog.com/2018/08/magnificent-mentors-of-gsoc.html'>Magnificent mentors of Google Summer of Code 2018</a> </h3> <div class='post-header'> <h4 class='date-header'><span>Thursday, August 2, 2018</span></h4> </div> <div class='post-body entry-content' id='post-body-2088581913953489546' itemprop='description articleBody'> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggrFw8R5ypI1e7ryvFKodqrUo-itOn0hPItl8h0cp7QNvMLBjC_DDvEEU3OIEO9k9grr_VQT9hHTl2nmLvgoM-asYGM5qw2Y6NXwYIXqqoJImr7ZmkLC0THfEIVuYdqwya2IhYD-msadA/s1600/GSoC+-+Vertical+Narrow+-+Gray+Text+-+White+BG.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="1600" data-original-width="1600" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggrFw8R5ypI1e7ryvFKodqrUo-itOn0hPItl8h0cp7QNvMLBjC_DDvEEU3OIEO9k9grr_VQT9hHTl2nmLvgoM-asYGM5qw2Y6NXwYIXqqoJImr7ZmkLC0THfEIVuYdqwya2IhYD-msadA/s200/GSoC+-+Vertical+Narrow+-+Gray+Text+-+White+BG.png" width="200" /></a></div> Mentors are the heart and soul of the <a href="https://g.co/gsoc">Google Summer of Code</a> (GSoC) program and have been for the last 14 years. Without their hard work and dedication, there would be no Google Summer of Code. These volunteers spend 4+ months guiding their students to create the best quality project possible while welcoming them into their communities &#8211; answering questions and providing help at all hours of the day, including weekends and holidays.<br /> <i><br /></i> <i>Thank you mentors and organization administrators!&nbsp;</i><br /> <br /> Each year we pore over heaps of data to extract some interesting statistics about the GSoC mentors. Here&#8217;s a quick synopsis of our 2018 crew:<br /> <ul> <li>Registered mentors: 2,819</li> <li>Mentors with assigned student projects: 1,996</li> <li>Mentors who have participated in GSoC for 10 or more years: 46</li> <li>Mentors who have been a part of GSoC for 5 years or more: 272</li> <li>Mentors that are former GSoC students: 627</li> <li>Mentors that have also been involved in the Google Code-in program: 474</li> <li>Percentage of new mentors: 36.5%</li> </ul> GSoC 2018 mentors are from all parts of the world, hailing from 75 countries!<br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBz9k1MJX8gM38d8m-mtnQ1qYX3wC2G2sJ8fAEbQ0jbFIy-B-lZsby107wBQT-ZvHDY2bb5aMn-n07gYdrcthvlLVoad6RtY1SbP6gL8j0a-ZkIh3hLsB12_lwaVtmOHf9XhjT2Tu_gcc/s1600/2018-08-01_14-50-10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="361" data-original-width="529" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBz9k1MJX8gM38d8m-mtnQ1qYX3wC2G2sJ8fAEbQ0jbFIy-B-lZsby107wBQT-ZvHDY2bb5aMn-n07gYdrcthvlLVoad6RtY1SbP6gL8j0a-ZkIh3hLsB12_lwaVtmOHf9XhjT2Tu_gcc/s1600/2018-08-01_14-50-10.png" /></a></div> <div class="separator" style="clear: both; text-align: left;"> If you want to see the stats for all 75 countries&nbsp;<a href="https://drive.google.com/open?id=1ZOcgj3dyqQwSBwHJr4Wr4NQ4y7Zyp7AH">check out this list</a>.</div> <div class="separator" style="clear: both; text-align: center;"> <br /></div> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBwP1zpGt2JNgvkRNvxgxFSuj6G5b0vVmytKeOfFvDoPiDwTlhhWO4y3LFl05Quu-_h_S41EUI4g2KvW0LNwALCzF2pBH4cal_NcpeXQKeryFQIDC7TIxD1CpJgjz_rKw7X0Fi4g3LgXo/s1600/map.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="446" data-original-width="710" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBwP1zpGt2JNgvkRNvxgxFSuj6G5b0vVmytKeOfFvDoPiDwTlhhWO4y3LFl05Quu-_h_S41EUI4g2KvW0LNwALCzF2pBH4cal_NcpeXQKeryFQIDC7TIxD1CpJgjz_rKw7X0Fi4g3LgXo/s1600/map.png" /></a></div> <br /> Another fun fact about our 2018 mentors: they range in age from 15-80 years old!<br /> <ul> <li>Average mentor age: 34</li> <li>Median mentor age: 33</li> <li>Mentors under 18 years old: 26*</li> </ul> GSoC mentors help introduce the next generation to the world of open source software development &#8211; for that we are very grateful. To show our appreciation, we invite two mentors from each of the 206 <a href="https://summerofcode.withgoogle.com/organizations/">participating organizations</a> to attend our <a href="https://www.youtube.com/watch?v=O6hUaXucUOs">annual mentor summit</a> at the Google campus in Sunnyvale, California. It&#8217;s three days of community building, lively debate, learning best practices from one another, working to strengthen open source communities, good food, and lots and lots of chocolate.<br /> <br /> Thank you to all of our mentors, organization administrators, and all of the &#8220;unofficial&#8221; mentors that help in the various open source organization&#8217;s communities. Google Summer of Code is a community effort and we appreciate each and every one of you.<br /> <br /> Cheers to yet another great year!<br /> <br /> <i>By Stephanie Taylor, Google Open Source</i><br /> <br /> <i>* Most of these 26 young GSoC mentors started their journey in Google Code-in, our contest for 13-17 year olds that introduces young students to open source software development.</i> <div style='clear: both;'></div> </div> </div> </div> <div class='post-footer'> </div> </div></div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5OCKDJLS2fOufaH99S7-BcQ7QTWSnhgD3fDAX43-I0yymKlss1WDJSPML5HbW6hGVFLOsbGThI2uBkr8q6qznIbU5fjzidfrSxWVkFqP5Nrbny39kKEXrTbhsdK_lW0ePywWiPzhDaGc/s200/cirq.png' itemprop='image_url'/> <meta content='8698702854482141883' itemprop='blogId'/> <meta content='4344917762203470629' itemprop='postId'/> <a name='4344917762203470629'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='https://opensource.googleblog.com/2018/08/cirq-open-source-framework-nisq-algorithms.html'>Announcing Cirq: an open source framework for NISQ algorithms</a> </h3> <div class='post-header'> <h4 class='date-header'><span>Wednesday, August 1, 2018</span></h4> </div> <div class='post-body entry-content' id='post-body-4344917762203470629' itemprop='description articleBody'> <i>Cross-posted from the <a href="https://ai.googleblog.com/2018/07/announcing-cirq-open-source-framework.html">Google AI Blog</a></i><br /> <br /> Over the past few years, <a href="https://en.wikipedia.org/wiki/Quantum_computing">quantum computing</a> has experienced a growth not only in the construction of quantum hardware, but also in the development of <a href="https://research.googleblog.com/2018/03/reformulating-chemistry-for-more.html">quantum algorithms</a>. With the availability of <a href="https://arxiv.org/abs/1801.00862">Noisy Intermediate Scale Quantum</a> (NISQ) computers (devices with ~50 - 100 qubits and high fidelity quantum gates), the development of algorithms to understand the power of these machines is of increasing importance. However, a common problem when designing a quantum algorithm on a NISQ processor is how to take full advantage of these limited quantum devices&#8212;using resources to solve the hardest part of the problem rather than on overheads from poor mappings between the algorithm and hardware. Furthermore some quantum processors have complex geometric constraints and other nuances, and ignoring these will either result in faulty quantum computation, or a computation that is modified and sub-optimal.<a href="#1" name="top1">*</a><br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5OCKDJLS2fOufaH99S7-BcQ7QTWSnhgD3fDAX43-I0yymKlss1WDJSPML5HbW6hGVFLOsbGThI2uBkr8q6qznIbU5fjzidfrSxWVkFqP5Nrbny39kKEXrTbhsdK_lW0ePywWiPzhDaGc/s1600/cirq.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="1219" data-original-width="1600" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5OCKDJLS2fOufaH99S7-BcQ7QTWSnhgD3fDAX43-I0yymKlss1WDJSPML5HbW6hGVFLOsbGThI2uBkr8q6qznIbU5fjzidfrSxWVkFqP5Nrbny39kKEXrTbhsdK_lW0ePywWiPzhDaGc/s200/cirq.png" width="200" /></a></div> Today at the <a href="https://www.tqc2018.org/">First International Workshop on Quantum Software and Quantum Machine Learning</a> (QSML), the <a href="https://ai.google/research/teams/applied-science/quantum-ai/">Google AI Quantum</a> team announced the <a href="https://github.com/quantumlib/cirq">public alpha of Cirq</a>, an open source framework for NISQ computers. Cirq is focused on near-term questions and helping researchers understand whether NISQ quantum computers are capable of solving <a href="https://ai.google/research/pubs/pub45919">computational problems of practical importance</a>. Cirq is licensed under <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache 2</a>, and is free to be modified or embedded in any commercial or open source package.<br /> <br /> Once <a href="https://github.com/quantumlib/Cirq/blob/master/docs/install.md">installed</a>, Cirq enables researchers to write quantum algorithms for specific quantum processors. Cirq gives users fine tuned control over quantum circuits, specifying gate behavior using native gates, placing these gates appropriately on the device, and scheduling the timing of these gates within the constraints of the quantum hardware. Data structures are optimized for writing and compiling these quantum circuits to allow users to get the most out of NISQ architectures. Cirq supports running these algorithms locally on a simulator, and is designed to easily integrate with future quantum hardware or larger simulators via the cloud.<br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpGNyB4nprlcAOHAQg3lyP0znGMJiBRxnmDjXqT7kOGZgR5kXwBNHVxavnX1VPMUiFoxtJ6_hhCArxeW7uetUJyTvAniCwTJNM1vD2gkKWMxW21VkuUoPRVUmNL8KSXkZQZlGFaYAAmKA/s1600/openfermion-cirq.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="67" data-original-width="544" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpGNyB4nprlcAOHAQg3lyP0znGMJiBRxnmDjXqT7kOGZgR5kXwBNHVxavnX1VPMUiFoxtJ6_hhCArxeW7uetUJyTvAniCwTJNM1vD2gkKWMxW21VkuUoPRVUmNL8KSXkZQZlGFaYAAmKA/s1600/openfermion-cirq.png" /></a></div> <br /> We are also announcing the release of <a href="https://github.com/quantumlib/OpenFermion-Cirq">OpenFermion-Cirq</a>, an example of a Cirq based application enabling near-term algorithms. <a href="https://github.com/quantumlib/OpenFermion">OpenFermion</a> is a platform for developing quantum algorithms for chemistry problems, and OpenFermion-Cirq is an open source library which compiles quantum simulation algorithms to Cirq. The new library uses the <a href="https://research.googleblog.com/2018/03/reformulating-chemistry-for-more.html">latest advances</a> in building low depth quantum algorithms for quantum chemistry problems to enable users to go from the details of a chemical problem to highly optimized quantum circuits customized to run on particular hardware. For example, this library can be used to easily build quantum variational algorithms for simulating properties of molecules and complex materials.<br /> <br /> Quantum computing will require strong cross-industry and academic collaborations if it is going to realize its full potential. In building Cirq, we worked with early testers to gain feedback and insight into algorithm design for NISQ computers. Below are some examples of Cirq work resulting from these early adopters:<br /> <ul> <li><a href="https://zapatacomputing.com/press/zapata_cirq_press_release.pdf">Zapata Computing</a>: simulation of a <a href="https://www.youtube.com/watch?v=WX6eYkmsu0g&amp;feature=youtu.be">quantum autoencoder</a> (<a href="https://github.com/zapatacomputing/cusp_cirq_demo/">example code</a>, <a href="https://youtu.be/79Hd-M_xN3Q">video tutorial</a>)</li> <li><a href="https://www.qcware.com/press/20180718">QC Ware</a>: QAOA implementation and integration into QC Ware&#8217;s AQUA platform (<a href="https://github.com/qcware/public_demos/blob/master/max_cut/max_cut_cirq.py">example code</a>, <a href="https://www.youtube.com/watch?v=pveM3j4uSTo&amp;feature=youtu.be">video tutorial</a>)</li> <li><a href="http://quantumbenchmark.com/quantum-computing-just-got-better/">Quantum Benchmark</a>: integration of True-Q software tools for assessing and extending hardware capabilities (<a href="https://www.youtube.com/watch?v=JWHWs7R-IRs&amp;feature=youtu.be">video tutorial</a>)</li> <li><a href="https://heisenberg.xyz/news/2018/07/heisenberg-cirq/">Heisenberg Quantum Simulations</a>: simulating the <a href="https://en.wikipedia.org/wiki/Anderson_impurity_model">Anderson Model</a></li> <li><a href="https://cambridgequantum.com/2018/07/18/cambridge-quantum-computing-and-google-launch-quantum-computing-partnership">Cambridge Quantum Computing</a>: integration of proprietary quantum compiler t|ket&gt; (<a href="https://www.youtube.com/watch?v=f4jhD4J3-W8&amp;feature=youtu.be">video tutorial</a>)</li> <li><a href="https://ti.arc.nasa.gov/tech/dash/groups/physics/quail/">NASA</a>: architecture-aware compiler based on <a href="https://arxiv.org/abs/1705.08927">temporal-planning for QAOA</a> (<a href="https://drive.google.com/open?id=1O-Ar44mJweLmVK3S1sPBrrV8X7ulB7EC">slides</a>) and simulator of quantum computers (<a href="https://drive.google.com/open?id=1EgAzSt8eM9bfRvGqrZ2LQa9rC0diu1tJ">slides</a>)</li> </ul> To learn more about how Cirq is helping enable NISQ algorithms, please visit the links above where many of the adopters have provided example source code for their implementations.<br /> <br /> Today, the Google AI Quantum team is using Cirq to create circuits that run on Google&#8217;s <a href="https://ai.googleblog.com/2018/03/a-preview-of-bristlecone-googles-new.html">Bristlecone processor</a>. In the future, we plan to make this processor available in the cloud, and Cirq will be the interface in which users write programs for this processor. In the meantime, we hope Cirq will improve the productivity of NISQ algorithm developers and researchers everywhere. Please check out the GitHub repositories for <a href="https://github.com/quantumlib/Cirq">Cirq</a> and <a href="https://github.com/quantumlib/OpenFermion-Cirq">OpenFermion-Cirq</a> &#8212; pull requests welcome!<br /> <br /> <i>By Alan Ho, Product Lead and Dave Bacon, Software Lead, Google AI Quantum Team</i><br /> <i><br /></i> <b>Acknowledgements</b><br /> We would like to thank Craig Gidney for leading the development of Cirq, Ryan Babbush and Kevin Sung for building OpenFermion-Cirq and a whole host of code contributors to both frameworks.<br /> <br /> <hr style="width:100%;"> <br /> <span style="font-size: small;"><a href="#1" name="1"><b>*</b></a> An analogous situation is how early classical programmers needed to run complex programs in very small memory spaces by paying careful attention to the lowest level details of the hardware.<a href="#top1"><sup>&#8617;</sup></a></span> <div style='clear: both;'></div> </div> </div> </div> <div class='post-footer'> </div> </div></div> </div> <div class='blog-pager' id='blog-pager'> <a class='home-link' href='https://opensource.googleblog.com/'> <i class='material-icons'> &#59530; </i> </a> <span id='blog-pager-newer-link'> <a class='blog-pager-newer-link' href='https://opensource.googleblog.com/search?updated-max=2018-10-15T09:00:00-07:00&max-results=3&reverse-paginate=true' id='Blog1_blog-pager-newer-link' title='Newer Posts'> <i class='material-icons'> &#58820; </i> </a> </span> <span id='blog-pager-older-link'> <a class='blog-pager-older-link' href='https://opensource.googleblog.com/search?updated-max=2018-08-01T11:21:00-07:00&max-results=3' id='Blog1_blog-pager-older-link' title='Older Posts'> <i class='material-icons'> &#58824; </i> </a> </span> </div> <div class='clear'></div> <div class='clear'></div> </div></div> </div> </div> <div class='column-right-outer'> <div class='column-right-inner'> <aside> <div class='sidebar section' id='sidebar-right-1'><div class='widget HTML' data-version='1' id='HTML4'> <div class='widget-content'> <div class='searchBox'><input type='text' title='Search This Blog' placeholder='Search blog...' /></div> </div> <div class='clear'></div> </div><div class='widget PopularPosts' data-version='1' id='PopularPosts1'> <h2>Popular Posts</h2> <div class='widget-content popular-posts'> <ul> <li> <a href='https://opensource.googleblog.com/2023/06/rust-fact-vs-fiction-5-insights-from-googles-rust-journey-2022.html'>Rust fact vs. fiction: 5 Insights from Google's Rust journey in 2022</a> </li> <li> <a href='https://opensource.googleblog.com/2025/01/google-summer-of-code-2025-is-here.html'>Google Summer of Code 2025 is here!</a> </li> <li> <a href='https://opensource.googleblog.com/2024/05/google-summer-of-code-2024-accepted-contributors-announced.html'>Google Summer of Code 2024 accepted contributors announced!</a> </li> <li> <a href='https://opensource.googleblog.com/2024/04/introducing-jpegli-new-jpeg-coding-library.html'>Introducing Jpegli: A New JPEG Coding Library</a> </li> <li> <a href='https://opensource.googleblog.com/2025/01/see-code-that-powered-pebble-smartwatches.html'>See the code that powered the Pebble smartwatches</a> </li> </ul> <div class='clear'></div> </div> </div><div class='widget BlogArchive' data-version='1' id='BlogArchive1'> <div class='tab'> <h2> Archive </h2> </div> <div class='widget-content'> <div id='ArchiveList'> <div id='BlogArchive1_ArchiveList'> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2025/'> 2025 </a> <span class='post-count'>(8)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2025/02/'> February </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2025/01/'> January </a> <span class='post-count'>(5)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/'> 2024 </a> <span class='post-count'>(39)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/12/'> December </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/11/'> November </a> <span class='post-count'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/10/'> October </a> <span class='post-count'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/09/'> September </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/08/'> August </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/07/'> July </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/06/'> June </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/05/'> May </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/04/'> April </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/03/'> March </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/02/'> February </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2024/01/'> January </a> <span class='post-count'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/'> 2023 </a> <span class='post-count'>(44)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/12/'> December </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/11/'> November </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/10/'> October </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/09/'> September </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/08/'> August </a> <span class='post-count'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/07/'> July </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/06/'> June </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/05/'> May </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/04/'> April </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/03/'> March </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/02/'> February </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2023/01/'> January </a> <span class='post-count'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/'> 2022 </a> <span class='post-count'>(44)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/12/'> December </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/11/'> November </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/10/'> October </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/09/'> September </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/08/'> August </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/07/'> July </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/06/'> June </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/05/'> May </a> <span class='post-count'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/04/'> April </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/03/'> March </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/02/'> February </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2022/01/'> January </a> <span class='post-count'>(3)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/'> 2021 </a> <span class='post-count'>(55)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/12/'> December </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/11/'> November </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/10/'> October </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/09/'> September </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/08/'> August </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/06/'> June </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/05/'> May </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/04/'> April </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/03/'> March </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/02/'> February </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2021/01/'> January </a> <span class='post-count'>(5)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/'> 2020 </a> <span class='post-count'>(83)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/12/'> December </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/11/'> November </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/10/'> October </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/09/'> September </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/08/'> August </a> <span class='post-count'>(13)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/07/'> July </a> <span class='post-count'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/06/'> June </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/05/'> May </a> <span class='post-count'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/04/'> April </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/03/'> March </a> <span class='post-count'>(13)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/02/'> February </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2020/01/'> January </a> <span class='post-count'>(5)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/'> 2019 </a> <span class='post-count'>(65)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/12/'> December </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/11/'> November </a> <span class='post-count'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/10/'> October </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/09/'> September </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/08/'> August </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/07/'> July </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/06/'> June </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/05/'> May </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/04/'> April </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/03/'> March </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/02/'> February </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2019/01/'> January </a> <span class='post-count'>(3)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> &#9660;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/'> 2018 </a> <span class='post-count'>(59)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/12/'> December </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/11/'> November </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/10/'> October </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/09/'> September </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> &#9660;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/08/'> August </a> <span class='post-count'>(10)</span> <ul class='posts'> <li><a href='https://opensource.googleblog.com/2018/08/introducing-tink-cryptographic-library.html'>Introducing the Tink cryptographic software library</a></li> <li><a href='https://opensource.googleblog.com/2018/08/announcing-google-code-in-2018.html'>Announcing Google Code-in 2018: nine is just fine!</a></li> <li><a href='https://opensource.googleblog.com/2018/08/thats-a-wrap-gsoc-2018.html'>That&#8217;s a wrap for Google Summer of Code 2018</a></li> <li><a href='https://opensource.googleblog.com/2018/08/zurihac-2018-haskell-hackathon-in.html'>ZuriHac 2018: Haskell hackathon in Rapperswil</a></li> <li><a href='https://opensource.googleblog.com/2018/08/congratulations-to-open-source-peer-bonus-winners.html'>Congratulations to the latest Google Open Source P...</a></li> <li><a href='https://opensource.googleblog.com/2018/08/how-we-brought-latest-python-to-app-engine.html'>How we brought the latest version of Python to App...</a></li> <li><a href='https://opensource.googleblog.com/2018/08/openmetrics-project-accepted-into-cncf.html'>OpenMetrics project accepted into CNCF Sandbox</a></li> <li><a href='https://opensource.googleblog.com/2018/08/introducing-new-lead-for-android.html'>Introducing the new lead for Android Open Source P...</a></li> <li><a href='https://opensource.googleblog.com/2018/08/magnificent-mentors-of-gsoc.html'>Magnificent mentors of Google Summer of Code 2018</a></li> <li><a href='https://opensource.googleblog.com/2018/08/cirq-open-source-framework-nisq-algorithms.html'>Announcing Cirq: an open source framework for NISQ...</a></li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/07/'> July </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/06/'> June </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/05/'> May </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/04/'> April </a> <span class='post-count'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/03/'> March </a> <span class='post-count'>(16)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/02/'> February </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2018/01/'> January </a> <span class='post-count'>(8)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/'> 2017 </a> <span class='post-count'>(73)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/12/'> December </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/11/'> November </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/10/'> October </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/09/'> September </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/08/'> August </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/07/'> July </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/06/'> June </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/05/'> May </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/04/'> April </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/03/'> March </a> <span class='post-count'>(13)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/02/'> February </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2017/01/'> January </a> <span class='post-count'>(13)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/'> 2016 </a> <span class='post-count'>(85)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/12/'> December </a> <span class='post-count'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/11/'> November </a> <span class='post-count'>(13)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/10/'> October </a> <span class='post-count'>(13)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/09/'> September </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/08/'> August </a> <span class='post-count'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/07/'> July </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/06/'> June </a> <span class='post-count'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/05/'> May </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/04/'> April </a> <span class='post-count'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/03/'> March </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/02/'> February </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2016/01/'> January </a> <span class='post-count'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/'> 2015 </a> <span class='post-count'>(80)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/12/'> December </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/11/'> November </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/10/'> October </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/09/'> September </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/08/'> August </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/07/'> July </a> <span class='post-count'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/06/'> June </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/05/'> May </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/04/'> April </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/03/'> March </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/02/'> February </a> <span class='post-count'>(11)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2015/01/'> January </a> <span class='post-count'>(8)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/'> 2014 </a> <span class='post-count'>(104)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/12/'> December </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/11/'> November </a> <span class='post-count'>(12)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/10/'> October </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/09/'> September </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/08/'> August </a> <span class='post-count'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/07/'> July </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/06/'> June </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/05/'> May </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/04/'> April </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/03/'> March </a> <span class='post-count'>(11)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/02/'> February </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2014/01/'> January </a> <span class='post-count'>(10)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/'> 2013 </a> <span class='post-count'>(100)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/12/'> December </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/11/'> November </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/10/'> October </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/09/'> September </a> <span class='post-count'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/08/'> August </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/07/'> July </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/06/'> June </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/05/'> May </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/04/'> April </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/03/'> March </a> <span class='post-count'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/02/'> February </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2013/01/'> January </a> <span class='post-count'>(8)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/'> 2012 </a> <span class='post-count'>(93)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/12/'> December </a> <span class='post-count'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/11/'> November </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/10/'> October </a> <span class='post-count'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/09/'> September </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/08/'> August </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/07/'> July </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/06/'> June </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/05/'> May </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/04/'> April </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/03/'> March </a> <span class='post-count'>(15)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/02/'> February </a> <span class='post-count'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2012/01/'> January </a> <span class='post-count'>(7)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/'> 2011 </a> <span class='post-count'>(117)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/12/'> December </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/11/'> November </a> <span class='post-count'>(14)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/10/'> October </a> <span class='post-count'>(13)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/09/'> September </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/08/'> August </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/07/'> July </a> <span class='post-count'>(13)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/06/'> June </a> <span class='post-count'>(11)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/05/'> May </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/04/'> April </a> <span class='post-count'>(11)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/03/'> March </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/02/'> February </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2011/01/'> January </a> <span class='post-count'>(7)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/'> 2010 </a> <span class='post-count'>(123)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/12/'> December </a> <span class='post-count'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/11/'> November </a> <span class='post-count'>(12)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/10/'> October </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/09/'> September </a> <span class='post-count'>(14)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/08/'> August </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/07/'> July </a> <span class='post-count'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/06/'> June </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/05/'> May </a> <span class='post-count'>(11)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/04/'> April </a> <span class='post-count'>(14)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/03/'> March </a> <span class='post-count'>(13)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/02/'> February </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2010/01/'> January </a> <span class='post-count'>(5)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/'> 2009 </a> <span class='post-count'>(124)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/12/'> December </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/11/'> November </a> <span class='post-count'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/10/'> October </a> <span class='post-count'>(11)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/09/'> September </a> <span class='post-count'>(11)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/08/'> August </a> <span class='post-count'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/07/'> July </a> <span class='post-count'>(13)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/06/'> June </a> <span class='post-count'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/05/'> May </a> <span class='post-count'>(11)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/04/'> April </a> <span class='post-count'>(16)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/03/'> March </a> <span class='post-count'>(17)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/02/'> February </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2009/01/'> January </a> <span class='post-count'>(10)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/'> 2008 </a> <span class='post-count'>(167)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/12/'> December </a> <span class='post-count'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/11/'> November </a> <span class='post-count'>(11)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/10/'> October </a> <span class='post-count'>(13)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/09/'> September </a> <span class='post-count'>(16)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/08/'> August </a> <span class='post-count'>(12)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/07/'> July </a> <span class='post-count'>(20)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/06/'> June </a> <span class='post-count'>(14)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/05/'> May </a> <span class='post-count'>(21)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/04/'> April </a> <span class='post-count'>(16)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/03/'> March </a> <span class='post-count'>(17)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://opensource.googleblog.com/2008/02/'> February </a> <span class='post-count'>(17)</span> </li> </ul> </li> </ul> </div> </div> <div class='clear'></div> </div> </div><div class='widget HTML' data-version='1' id='HTML3'> <div class='widget-content'> <div class="share"> <a href="https://twitter.com/GoogleOSS"><img alt="Twitter" height="24" src="https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png" width="24" /></a> <a href="https://www.youtube.com/GoogleOpenSource"><img alt="YouTube" height="24" src="https://www.gstatic.com/images/icons/material/system/2x/post_youtube_black_24dp.png" width="24" /></a> </div> </div> <div class='clear'></div> </div></div> </aside> </div> </div> </div> <div style='clear: both'></div> </div> </div> </div> </section> </div> <footer class='footer-main' id='FooterMain'> <div class='col-wrap'> <nav class='footer-nav pull-left'> <ul> <li class='google'> <a href="//google.com" title="Google"> Google </a> </li> <li> <a href='https://www.google.com/policies/privacy/' title='Privacy'> Privacy </a> </li> <li> <a href='https://www.google.com/policies/terms/' title='Terms'> Terms </a> </li> </ul> </nav> </div> </footer> </div> <div id='ogc-shim'> <a href='#' id='SendFeedback'>.</a> </div> <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script> <script async='async' src='https://support.google.com/inapp/api.js' type='text/javascript'></script> <script type='text/javascript'> //<![CDATA[ $(document).ready(function(){ var DocEl = document.documentElement; DocEl.className = DocEl.className.replace('no-js', 'js'); var NavTriggerEl = document.getElementById("NavTrigger"); var BodyEl = document.body; var ShadowBoxEl = document.createElement("div"); ShadowBoxEl.id = "ShadowBox"; BodyEl.appendChild(ShadowBoxEl); NavTriggerEl.addEventListener("click", function(e){ e.preventDefault(); toggleActiveClass(); }); ShadowBoxEl.addEventListener("click", function(){ toggleActiveClass(); }); $('a:not(.internal):not([href^="https://opensource.googleblog.com"]):not([href^="http://opensource.googleblog.com"]):not([href^="https://opensource.google.com"]):not([href^="http://opensource.google.com"]):not([href^="#"]):not([href^="/"]):not([href^="javascript"]):not([href^="mailto"])').addClass('external'); $('a.external').attr("target", "_blank"); }); // Social sharing popups. var postEl = document.getElementsByClassName('social-wrapper'); var postCount = postEl.length; for(i=0; i<postCount;i++){ postEl[i].addEventListener("click", function(event){ var postUrl = this.getAttribute("data-href"); window.open( postUrl,'popUpWindow','height=500,width=500,left=10,top=10,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no,status=yes'); });} var postEl = document.getElementsByClassName('social-wrapper2'); var postCount = postEl.length; for(i=0; i<postCount;i++){ postEl[i].addEventListener("click", function(event){ var postUrl = this.getAttribute("data-href"); window.open( postUrl,'popUpWindow2','height=500,width=400,left=10,top=10,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no,status=yes'); });} function toggleActiveClass() { var stringIndex = document.body.className.indexOf("nav-active"); if (stringIndex < 0) { document.body.className += " nav-active"; } else { document.body.className = document.body.className.replace(" nav-active", ""); } } //]]> </script> <script type='text/javascript'> //<![CDATA[ var BreakpointHandler = function() { this.initted = false; this.isHomePage = false; this.isMobile = false; }; BreakpointHandler.prototype.finalizeSummary = function(summaryHtml, lastNode) { // Use $.trim for IE8 compatibility summaryHtml = $.trim(summaryHtml).replace(/(<br>|\s)+$/,''); if (lastNode.nodeType == 3) { var lastChar = summaryHtml.slice(-1); if (!lastChar.match(/[.”"?]/)) { if (!lastChar.match(/[A-Za-z]/)) { summaryHtml = summaryHtml.slice(0, -1); } summaryHtml += ' ...'; } } else if (lastNode.nodeType == 1 && (lastNode.nodeName == 'I' || lastNode.nodeName == 'A')) { summaryHtml += ' ...'; } return summaryHtml; }; BreakpointHandler.prototype.generateSummaryFromContent = function(content, numWords) { var seenWords = 0; var summaryHtml = ''; for (var i=0; i < content.childNodes.length; i++) { var node = content.childNodes[i]; var nodeText; if (node.nodeType == 1) { if (node.hasAttribute('data-about-pullquote')) { continue; } nodeText = node.textContent; if (nodeText === undefined) { // innerText for IE8 nodeText = node.innerText; } if (node.nodeName == 'DIV' || node.nodeName == 'B') { // Don't end early if we haven't seen enough words. if (seenWords < 10) { continue; } if (i > 0) { summaryHtml = this.finalizeSummary(summaryHtml, content.childNodes[i-1]); } break; } summaryHtml += node.outerHTML; } else if (node.nodeType == 3) { nodeText = node.nodeValue; summaryHtml += nodeText + ' '; } var words = nodeText.match(/\S+\s*/g); if (!words) { continue; } var remain = numWords - seenWords; if (words.length >= remain) { summaryHtml = this.finalizeSummary(summaryHtml, node); break; } seenWords += words.length; } return summaryHtml; }; BreakpointHandler.prototype.detect = function() { var match, pl = /\+/g, search = /([^&=]+)=?([^&]*)/g, decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, query = window.location.search.substring(1); var urlParams = {}; while (match = search.exec(query)) urlParams[decode(match[1])] = decode(match[2]); this.isListPage = $('html').hasClass('list-page'); this.isMobile = urlParams['m'] === '1'; this.isHomePage = window.location.pathname == '/'; }; BreakpointHandler.prototype.initContent = function() { var self = this; $('.post').each(function(index) { var body = $(this).children('.post-body')[0]; /*var content = $(body).children('.post-content')[0];*/ // XXX does not exist var content = body; $(content).addClass('post-original'); var data = $(content).children('script').html(); // XXX added this if block because data never seems to exist if (data) { data = self.rewriteForSSL(data); // If exists, extract specified editor's preview. var match = data.match(/([\s\S]+?)<div data-is-preview.+?>([\s\S]+)<\/div>/m); if (match) { data = match[1]; } // Prevent big images from loading when they aren't needed. // This must be done as a pre-injection step, since image loading can't be // canceled once embedded into the DOM. if (self.isListPage && self.isMobile) { data = data.replace(/<(img|iframe) .+?>/g, ''); } // Insert template to be rendered as nodes. content.innerHTML = data; } if (self.isListPage) { var summary = document.createElement('div'); $(summary).addClass('post-content'); $(summary).addClass('post-summary'); body.insertBefore(summary, content); if (match) { // Use provided summary. summary.innerHTML = match[2]; } else { // Generate a summary. // Summary generation relies on DOM, so it must occur after content is // inserted into the page. summary.innerHTML = self.generateSummaryFromContent(content, 30); } // Add read more link to summary. var titleAnchor = $(this).find('.title a')[0]; var link = titleAnchor.cloneNode(true); link.innerHTML = 'Read More'; $(link).addClass('read-more'); summary.appendChild(link); } }); // Firefox does not allow for proper styling of BR. if (navigator.userAgent.indexOf('Firefox') > -1) { $('.post-content br').replaceWith('<span class="space"></span>'); } }; BreakpointHandler.prototype.process = function() { if (!this.initted) { var makeInsecureImageRegex = function(hosts) { var whitelist = hosts.join('|').replace(/\./g,'\\.'); // Normal image tags, plus input images (yes, this is possible!) return new RegExp('(<(img|input)[^>]+?src=("|\'))http:\/\/(' + whitelist +')', 'g'); }; this.sslImageRegex = makeInsecureImageRegex(BreakpointHandler.KNOWN_HTTPS_HOSTS); this.sslImageCurrentDomainRegex = makeInsecureImageRegex([window.location.hostname]); this.detect(); this.initContent(); this.initted = true; } }; BreakpointHandler.KNOWN_HTTPS_HOSTS = [ "opensource.google.com", "www.google.org", "www.google.com", "services.google.com", "blogger.com", "draft.blogger.com", "www.blogger.com", "photos1.blogger.com", "photos2.blogger.com", "photos3.blogger.com", "blogblog.com", "img1.blogblog.com", "img2.blogblog.com", "www.blogblog.com", "www1.blogblog.com", "www2.blogblog.com", "0.bp.blogspot.com", "1.bp.blogspot.com", "2.bp.blogspot.com", "3.bp.blogspot.com", "4.bp.blogspot.com", "lh3.googleusercontent.com", "lh4.googleusercontent.com", "lh5.googleusercontent.com", "lh6.googleusercontent.com", "themes.googleusercontent.com", ]; BreakpointHandler.prototype.rewriteForSSL = function(html) { // Handle HTTP -> HTTPS source replacement of images, movies, and other embedded content. return html.replace(this.sslImageRegex, '$1https://$4') .replace(this.sslImageCurrentDomainRegex, '$1//$4') .replace(/(<(embed|iframe)[^>]+?src=("|'))http:\/\/([^"']*?(youtube|picasaweb\.google)\.com)/g, '$1https://$4') // Slideshow SWF takes a image host, so we need to rewrite that parameter. .replace(/(<embed[^>]+?feed=http(?=[^s]))/g, '$1s'); }; $(document).ready(function() { var handler = new BreakpointHandler(); handler.process(); // Top-level navigation. $(".BlogArchive .tab").click(function(ev) { ev.preventDefault(); $(this).parent().toggleClass('active'); if ($(this).parent().hasClass('active')) { $(this).siblings().css('display', 'block'); } else { $(this).siblings().css('display', 'none'); } }); $(".Label .tab").click(function(ev) { ev.preventDefault(); $(this).parent().toggleClass('active'); if ($(this).parent().hasClass('active')) { $(this).siblings().css('display', 'block'); } else { $(this).siblings().css('display', 'none'); } }); // Blog archive year expansion. $('.BlogArchive .intervalToggle').click(function(ev) { ev.preventDefault(); if ($(this).parent().hasClass('collapsed')) { $(this).parent().removeClass('collapsed'); $(this).parent().addClass('expanded'); } else { $(this).parent().removeClass('expanded'); $(this).parent().addClass('collapsed'); } }); // Reverse order of months. $('.BlogArchive .intervalToggle + div').each(function(_, items) { var year = $(this); year.children().each(function(_, month) { year.prepend(month); }); }); // Process search requests. $('.searchBox input').on("keypress", function(ev) { if (ev.which == 13) { window.location.href = 'https://www.google.com/search?q=site%3A' + window.location.hostname + '%20' + encodeURIComponent ($(this).val()); } }); }); //]]> </script> <link href='https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css' rel='stylesheet' type='text/css'/> <script language='javascript' src='https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js' type='text/javascript'></script> <script language='javascript' src='https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/lang-css.min.js' type='text/javascript'></script> <script type='text/javascript'> document.addEventListener('DOMContentLoaded',function() { prettyPrint(); }); </script> <script type='text/javascript'> //<![CDATA[ (function(){var f,aa="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(c.get||c.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)},k="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:this;function ba(){ba=function(){};k.Symbol||(k.Symbol=ca)}var da=0;function ca(a){return"jscomp_symbol_"+(a||"")+da++} function l(){ba();var a=k.Symbol.iterator;a||(a=k.Symbol.iterator=k.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&aa(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return ea(this)}});l=function(){}}function ea(a){var b=0;return fa(function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}})}function fa(a){l();a={next:a};a[k.Symbol.iterator]=function(){return this};return a} function m(a){if(!(a instanceof Array)){l();var b=a[Symbol.iterator];a=b?b.call(a):ea(a);for(var c=[];!(b=a.next()).done;)c.push(b.value);a=c}return a}function ha(a,b){function c(){}c.prototype=b.prototype;a.ha=b.prototype;a.prototype=new c;a.prototype.constructor=a;for(var d in b)if(Object.defineProperties){var e=Object.getOwnPropertyDescriptor(b,d);e&&Object.defineProperty(a,d,e)}else a[d]=b[d]} var n=window.Element.prototype,ia=n.matches||n.matchesSelector||n.webkitMatchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector;function ja(a,b){if(a&&1==a.nodeType&&b){if("string"==typeof b||1==b.nodeType)return a==b||ka(a,b);if("length"in b)for(var c=0,d;d=b[c];c++)if(a==d||ka(a,d))return!0}return!1}function ka(a,b){if("string"!=typeof b)return!1;if(ia)return ia.call(a,b);b=a.parentNode.querySelectorAll(b);for(var c=0,d;d=b[c];c++)if(d==a)return!0;return!1} function la(a){for(var b=[];a&&a.parentNode&&1==a.parentNode.nodeType;)a=a.parentNode,b.push(a);return b} function p(a,b,c){function d(a){var d;if(h.composed&&"function"==typeof a.composedPath)for(var e=a.composedPath(),g=0,E;E=e[g];g++)1==E.nodeType&&ja(E,b)&&(d=E);else a:{if((d=a.target)&&1==d.nodeType&&b)for(d=[d].concat(la(d)),e=0;g=d[e];e++)if(ja(g,b)){d=g;break a}d=void 0}d&&c.call(d,a,d)}var e=document,h={composed:!0,S:!0},h=void 0===h?{}:h;e.addEventListener(a,d,h.S);return{j:function(){e.removeEventListener(a,d,h.S)}}} function ma(a){var b={};if(!a||1!=a.nodeType)return b;a=a.attributes;if(!a.length)return{};for(var c=0,d;d=a[c];c++)b[d.name]=d.value;return b}var na=/:(80|443)$/,q=document.createElement("a"),r={}; function t(a){a=a&&"."!=a?a:location.href;if(r[a])return r[a];q.href=a;if("."==a.charAt(0)||"/"==a.charAt(0))return t(q.href);var b="80"==q.port||"443"==q.port?"":q.port,b="0"==b?"":b,c=q.host.replace(na,"");return r[a]={hash:q.hash,host:c,hostname:q.hostname,href:q.href,origin:q.origin?q.origin:q.protocol+"//"+c,pathname:"/"==q.pathname.charAt(0)?q.pathname:"/"+q.pathname,port:b,protocol:q.protocol,search:q.search}}var u=[]; function oa(a,b){var c=this;this.context=a;this.P=b;this.f=(this.c=/Task$/.test(b))?a.get(b):a[b];this.b=[];this.a=[];this.g=function(a){for(var b=[],d=0;d<arguments.length;++d)b[d-0]=arguments[d];return c.a[c.a.length-1].apply(null,[].concat(m(b)))};this.c?a.set(b,this.g):a[b]=this.g}function v(a,b,c){a=pa(a,b);a.b.push(c);qa(a)}function w(a,b,c){a=pa(a,b);c=a.b.indexOf(c);-1<c&&(a.b.splice(c,1),0<a.b.length?qa(a):a.j())} function qa(a){a.a=[];for(var b,c=0;b=a.b[c];c++){var d=a.a[c-1]||a.f.bind(a.context);a.a.push(b(d))}}oa.prototype.j=function(){var a=u.indexOf(this);-1<a&&(u.splice(a,1),this.c?this.context.set(this.P,this.f):this.context[this.P]=this.f)};function pa(a,b){var c=u.filter(function(c){return c.context==a&&c.P==b})[0];c||(c=new oa(a,b),u.push(c));return c} function x(a,b,c,d,e,h){if("function"==typeof d){var g=c.get("buildHitTask");return{buildHitTask:function(c){c.set(a,null,!0);c.set(b,null,!0);d(c,e,h);g(c)}}}return y({},a,b)}function z(a,b){var c=ma(a),d={};Object.keys(c).forEach(function(a){if(!a.indexOf(b)&&a!=b+"on"){var e=c[a];"true"==e&&(e=!0);"false"==e&&(e=!1);a=ra(a.slice(b.length));d[a]=e}});return d} function sa(a){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",function c(){document.removeEventListener("DOMContentLoaded",c);a()}):a()}function ta(a,b){var c;return function(d){for(var e=[],h=0;h<arguments.length;++h)e[h-0]=arguments[h];clearTimeout(c);c=setTimeout(function(){return a.apply(null,[].concat(m(e)))},b)}}function ua(a){function b(){c||(c=!0,a())}var c=!1;setTimeout(b,2E3);return b}var A={}; function va(a,b){function c(){clearTimeout(e.timeout);e.send&&w(a,"send",e.send);delete A[d];e.R.forEach(function(a){return a()})}var d=a.get("trackingId"),e=A[d]=A[d]||{};clearTimeout(e.timeout);e.timeout=setTimeout(c,0);e.R=e.R||[];e.R.push(b);e.send||(e.send=function(a){return function(b){for(var d=[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];c();a.apply(null,[].concat(m(d)))}},v(a,"send",e.send))} var y=Object.assign||function(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=arguments[d];for(var d=0,e=c.length;d<e;d++){var h=Object(c[d]),g;for(g in h)Object.prototype.hasOwnProperty.call(h,g)&&(a[g]=h[g])}return a};function ra(a){return a.replace(/[\-\_]+(\w?)/g,function(a,c){return c.toUpperCase()})}function B(a){return"object"==typeof a&&null!==a}var C=function wa(b){return b?(b^16*Math.random()>>b/4).toString(16):"10000000-1000-4000-8000-100000000000".replace(/[018]/g,wa)}; function F(a,b){var c=window.GoogleAnalyticsObject||"ga";window[c]=window[c]||function(a){for(var b=[],d=0;d<arguments.length;++d)b[d-0]=arguments[d];(window[c].q=window[c].q||[]).push(b)};window.gaDevIds=window.gaDevIds||[];0>window.gaDevIds.indexOf("i5iSjo")&&window.gaDevIds.push("i5iSjo");window[c]("provide",a,b);window.gaplugins=window.gaplugins||{};window.gaplugins[a.charAt(0).toUpperCase()+a.slice(1)]=b}var G={T:1,U:2,V:3,X:4,Y:5,Z:6,$:7,aa:8,ba:9,W:10},H=Object.keys(G).length; function I(a,b){a.set("\x26_av","2.3.3");var c=a.get("\x26_au"),c=parseInt(c||"0",16).toString(2);if(c.length<H)for(var d=H-c.length;d;)c="0"+c,d--;b=H-b;c=c.substr(0,b)+1+c.substr(b+1);a.set("\x26_au",parseInt(c||"0",2).toString(16))}function J(a,b){I(a,G.T);this.a=y({},b);this.g=a;this.b=this.a.stripQuery&&this.a.queryDimensionIndex?"dimension"+this.a.queryDimensionIndex:null;this.f=this.f.bind(this);this.c=this.c.bind(this);v(a,"get",this.f);v(a,"buildHitTask",this.c)} J.prototype.f=function(a){var b=this;return function(c){if("page"==c||c==b.b){var d={location:a("location"),page:a("page")};return xa(b,d)[c]}return a(c)}};J.prototype.c=function(a){var b=this;return function(c){var d=xa(b,{location:c.get("location"),page:c.get("page")});c.set(d,null,!0);a(c)}}; function xa(a,b){var c=t(b.page||b.location),d=c.pathname;if(a.a.indexFilename){var e=d.split("/");a.a.indexFilename==e[e.length-1]&&(e[e.length-1]="",d=e.join("/"))}"remove"==a.a.trailingSlash?d=d.replace(/\/+$/,""):"add"==a.a.trailingSlash&&(/\.\w+$/.test(d)||"/"==d.substr(-1)||(d+="/"));d={page:d+(a.a.stripQuery?"":c.search)};b.location&&(d.location=b.location);a.b&&(d[a.b]=c.search.slice(1)||"(not set)");return"function"==typeof a.a.urlFieldsFilter?(b=a.a.urlFieldsFilter(d,t),c={},c.page=b.page, c.location=b.location,c[a.b]=b[a.b],c):d}J.prototype.remove=function(){w(this.g,"get",this.f);w(this.g,"buildHitTask",this.c)};F("cleanUrlTracker",J);function K(a,b){var c=this;I(a,G.U);if(window.addEventListener){this.a=y({events:["click"],fieldsObj:{},attributePrefix:"ga-"},b);this.f=a;this.c=this.c.bind(this);var d="["+this.a.attributePrefix+"on]";this.b={};this.a.events.forEach(function(a){c.b[a]=p(a,d,c.c)})}} K.prototype.c=function(a,b){var c=this.a.attributePrefix;if(!(0>b.getAttribute(c+"on").split(/\s*,\s*/).indexOf(a.type))){var c=z(b,c),d=y({},this.a.fieldsObj,c);this.f.send(c.hitType||"event",x({transport:"beacon"},d,this.f,this.a.hitFilter,b,a))}};K.prototype.remove=function(){var a=this;Object.keys(this.b).forEach(function(b){a.b[b].j()})};F("eventTracker",K); function ya(a,b){var c=this;I(a,G.V);window.IntersectionObserver&&window.MutationObserver&&(this.a=y({rootMargin:"0px",fieldsObj:{},attributePrefix:"ga-"},b),this.c=a,this.M=this.M.bind(this),this.O=this.O.bind(this),this.K=this.K.bind(this),this.L=this.L.bind(this),this.b=null,this.items=[],this.i={},this.h={},sa(function(){c.a.elements&&c.observeElements(c.a.elements)}))}f=ya.prototype; f.observeElements=function(a){var b=this;a=L(this,a);this.items=this.items.concat(a.items);this.i=y({},a.i,this.i);this.h=y({},a.h,this.h);a.items.forEach(function(a){var c=b.h[a.threshold]=b.h[a.threshold]||new IntersectionObserver(b.O,{rootMargin:b.a.rootMargin,threshold:[+a.threshold]});(a=b.i[a.id]||(b.i[a.id]=document.getElementById(a.id)))&&c.observe(a)});this.b||(this.b=new MutationObserver(this.M),this.b.observe(document.body,{childList:!0,subtree:!0}));requestAnimationFrame(function(){})}; f.unobserveElements=function(a){var b=[],c=[];this.items.forEach(function(d){a.some(function(a){a=za(a);return a.id===d.id&&a.threshold===d.threshold&&a.trackFirstImpressionOnly===d.trackFirstImpressionOnly})?c.push(d):b.push(d)});if(b.length){var d=L(this,b),e=L(this,c);this.items=d.items;this.i=d.i;this.h=d.h;c.forEach(function(a){if(!d.i[a.id]){var b=e.h[a.threshold],c=e.i[a.id];c&&b.unobserve(c);d.h[a.threshold]||e.h[a.threshold].disconnect()}})}else this.unobserveAllElements()}; f.unobserveAllElements=function(){var a=this;Object.keys(this.h).forEach(function(b){a.h[b].disconnect()});this.b.disconnect();this.b=null;this.items=[];this.i={};this.h={}};function L(a,b){var c=[],d={},e={};b.length&&b.forEach(function(b){b=za(b);c.push(b);e[b.id]=a.i[b.id]||null;d[b.threshold]=a.h[b.threshold]||null});return{items:c,i:e,h:d}}f.M=function(a){for(var b=0,c;c=a[b];b++){for(var d=0,e;e=c.removedNodes[d];d++)M(this,e,this.L);for(d=0;e=c.addedNodes[d];d++)M(this,e,this.K)}}; function M(a,b,c){1==b.nodeType&&b.id in a.i&&c(b.id);for(var d=0,e;e=b.childNodes[d];d++)M(a,e,c)} f.O=function(a){for(var b=[],c=0,d;d=a[c];c++)for(var e=0,h;h=this.items[e];e++){var g;if(g=d.target.id===h.id)(g=h.threshold)?g=d.intersectionRatio>=g:(g=d.intersectionRect,g=0<g.top||0<g.bottom||0<g.left||0<g.right);if(g){var D=h.id;g=document.getElementById(D);var D={transport:"beacon",eventCategory:"Viewport",eventAction:"impression",eventLabel:D,nonInteraction:!0},Ma=y({},this.a.fieldsObj,z(g,this.a.attributePrefix));this.c.send("event",x(D,Ma,this.c,this.a.hitFilter,g));h.trackFirstImpressionOnly&& b.push(h)}}b.length&&this.unobserveElements(b)};f.K=function(a){var b=this,c=this.i[a]=document.getElementById(a);this.items.forEach(function(d){a==d.id&&b.h[d.threshold].observe(c)})};f.L=function(a){var b=this,c=this.i[a];this.items.forEach(function(d){a==d.id&&b.h[d.threshold].unobserve(c)});this.i[a]=null};f.remove=function(){this.unobserveAllElements()};F("impressionTracker",ya);function za(a){"string"==typeof a&&(a={id:a});return y({threshold:0,trackFirstImpressionOnly:!0},a)} function Aa(){this.a={}}function Ba(a,b){(a.a.externalSet=a.a.externalSet||[]).push(b)}Aa.prototype.ca=function(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=arguments[d];(this.a[a]=this.a[a]||[]).forEach(function(a){return a.apply(null,[].concat(m(c)))})};var N={},O=!1,P;function Q(a,b){b=void 0===b?{}:b;this.a={};this.b=a;this.w=b;this.l=null}ha(Q,Aa);function R(a,b,c){a=["autotrack",a,b].join(":");N[a]||(N[a]=new Q(a,c),O||(window.addEventListener("storage",Ca),O=!0));return N[a]} function S(){if(null!=P)return P;try{window.localStorage.setItem("autotrack","autotrack"),window.localStorage.removeItem("autotrack"),P=!0}catch(a){P=!1}return P}Q.prototype.get=function(){if(this.l)return this.l;if(S())try{this.l=Da(window.localStorage.getItem(this.b))}catch(a){}return this.l=y({},this.w,this.l)};Q.prototype.set=function(a){this.l=y({},this.w,this.l,a);if(S())try{var b=JSON.stringify(this.l);window.localStorage.setItem(this.b,b)}catch(c){}}; function Ea(a){a.l={};if(S())try{window.localStorage.removeItem(a.b)}catch(b){}}Q.prototype.j=function(){delete N[this.b];Object.keys(N).length||(window.removeEventListener("storage",Ca),O=!1)};function Ca(a){var b=N[a.key];if(b){var c=y({},b.w,Da(a.oldValue));a=y({},b.w,Da(a.newValue));b.l=a;b.ca("externalSet",a,c)}}function Da(a){var b={};if(a)try{b=JSON.parse(a)}catch(c){}return b}var T={}; function U(a,b,c){this.f=a;this.timeout=b||Fa;this.timeZone=c;this.b=this.b.bind(this);v(a,"sendHitTask",this.b);try{this.c=new Intl.DateTimeFormat("en-US",{timeZone:this.timeZone})}catch(d){}this.a=R(a.get("trackingId"),"session",{hitTime:0,isExpired:!1});this.a.get().id||this.a.set({id:C()})}function Ga(a,b,c){var d=a.get("trackingId");return T[d]?T[d]:T[d]=new U(a,b,c)}function V(a){return a.a.get().id} U.prototype.isExpired=function(a){a=void 0===a?V(this):a;if(a!=V(this))return!0;a=this.a.get();if(a.isExpired)return!0;var b=a.hitTime;return b&&(a=new Date,b=new Date(b),a-b>6E4*this.timeout||this.c&&this.c.format(a)!=this.c.format(b))?!0:!1};U.prototype.b=function(a){var b=this;return function(c){a(c);var d=c.get("sessionControl");c="start"==d||b.isExpired();var d="end"==d,e=b.a.get();e.hitTime=+new Date;c&&(e.isExpired=!1,e.id=C());d&&(e.isExpired=!0);b.a.set(e)}}; U.prototype.j=function(){w(this.f,"sendHitTask",this.b);this.a.j();delete T[this.f.get("trackingId")]};var Fa=30;function W(a,b){I(a,G.W);window.addEventListener&&(this.b=y({increaseThreshold:20,sessionTimeout:Fa,fieldsObj:{}},b),this.f=a,this.c=Ha(this),this.g=ta(this.g.bind(this),500),this.o=this.o.bind(this),this.a=R(a.get("trackingId"),"plugins/max-scroll-tracker"),this.m=Ga(a,this.b.sessionTimeout,this.b.timeZone),v(a,"set",this.o),Ia(this))} function Ia(a){100>(a.a.get()[a.c]||0)&&window.addEventListener("scroll",a.g)} W.prototype.g=function(){var a=document.documentElement,b=document.body,a=Math.min(100,Math.max(0,Math.round(window.pageYOffset/(Math.max(a.offsetHeight,a.scrollHeight,b.offsetHeight,b.scrollHeight)-window.innerHeight)*100))),b=V(this.m);b!=this.a.get().sessionId&&(Ea(this.a),this.a.set({sessionId:b}));if(this.m.isExpired(this.a.get().sessionId))Ea(this.a);else if(b=this.a.get()[this.c]||0,a>b&&(100!=a&&100!=b||window.removeEventListener("scroll",this.g),b=a-b,100==a||b>=this.b.increaseThreshold)){var c= {};this.a.set((c[this.c]=a,c.sessionId=V(this.m),c));a={transport:"beacon",eventCategory:"Max Scroll",eventAction:"increase",eventValue:b,eventLabel:String(a),nonInteraction:!0};this.b.maxScrollMetricIndex&&(a["metric"+this.b.maxScrollMetricIndex]=b);this.f.send("event",x(a,this.b.fieldsObj,this.f,this.b.hitFilter))}};W.prototype.o=function(a){var b=this;return function(c,d){a(c,d);var e={};(B(c)?c:(e[c]=d,e)).page&&(c=b.c,b.c=Ha(b),b.c!=c&&Ia(b))}}; function Ha(a){a=t(a.f.get("page")||a.f.get("location"));return a.pathname+a.search}W.prototype.remove=function(){this.m.j();window.removeEventListener("scroll",this.g);w(this.f,"set",this.o)};F("maxScrollTracker",W);var Ja={};function Ka(a,b){I(a,G.X);window.matchMedia&&(this.a=y({changeTemplate:this.changeTemplate,changeTimeout:1E3,fieldsObj:{}},b),B(this.a.definitions)&&(b=this.a.definitions,this.a.definitions=Array.isArray(b)?b:[b],this.b=a,this.c=[],La(this)))} function La(a){a.a.definitions.forEach(function(b){if(b.name&&b.dimensionIndex){var c=Na(b);a.b.set("dimension"+b.dimensionIndex,c);Oa(a,b)}})}function Na(a){var b;a.items.forEach(function(a){Pa(a.media).matches&&(b=a)});return b?b.name:"(not set)"} function Oa(a,b){b.items.forEach(function(c){c=Pa(c.media);var d=ta(function(){var c=Na(b),d=a.b.get("dimension"+b.dimensionIndex);c!==d&&(a.b.set("dimension"+b.dimensionIndex,c),c={transport:"beacon",eventCategory:b.name,eventAction:"change",eventLabel:a.a.changeTemplate(d,c),nonInteraction:!0},a.b.send("event",x(c,a.a.fieldsObj,a.b,a.a.hitFilter)))},a.a.changeTimeout);c.addListener(d);a.c.push({fa:c,da:d})})}Ka.prototype.remove=function(){for(var a=0,b;b=this.c[a];a++)b.fa.removeListener(b.da)}; Ka.prototype.changeTemplate=function(a,b){return a+" \x3d\x3e "+b};F("mediaQueryTracker",Ka);function Pa(a){return Ja[a]||(Ja[a]=window.matchMedia(a))}function X(a,b){I(a,G.Y);window.addEventListener&&(this.a=y({formSelector:"form",shouldTrackOutboundForm:this.shouldTrackOutboundForm,fieldsObj:{},attributePrefix:"ga-"},b),this.b=a,this.c=p("submit",this.a.formSelector,this.f.bind(this)))} X.prototype.f=function(a,b){var c={transport:"beacon",eventCategory:"Outbound Form",eventAction:"submit",eventLabel:t(b.action).href};if(this.a.shouldTrackOutboundForm(b,t)){navigator.sendBeacon||(a.preventDefault(),c.hitCallback=ua(function(){b.submit()}));var d=y({},this.a.fieldsObj,z(b,this.a.attributePrefix));this.b.send("event",x(c,d,this.b,this.a.hitFilter,b,a))}}; X.prototype.shouldTrackOutboundForm=function(a,b){a=b(a.action);return a.hostname!=location.hostname&&"http"==a.protocol.slice(0,4)};X.prototype.remove=function(){this.c.j()};F("outboundFormTracker",X); function Y(a,b){var c=this;I(a,G.Z);window.addEventListener&&(this.a=y({events:["click"],linkSelector:"a, area",shouldTrackOutboundLink:this.shouldTrackOutboundLink,fieldsObj:{},attributePrefix:"ga-"},b),this.f=a,this.c=this.c.bind(this),this.b={},this.a.events.forEach(function(a){c.b[a]=p(a,c.a.linkSelector,c.c)}))} Y.prototype.c=function(a,b){if(this.a.shouldTrackOutboundLink(b,t)){var c=b.getAttribute("href")||b.getAttribute("xlink:href"),d=t(c),e={transport:"beacon",eventCategory:"Outbound Link",eventAction:a.type,eventLabel:d.href};navigator.sendBeacon||"click"!=a.type||"_blank"==b.target||a.metaKey||a.ctrlKey||a.shiftKey||a.altKey||1<a.which||window.addEventListener("click",function(a){a.defaultPrevented||(a.preventDefault(),e.hitCallback=ua(function(){location.href=c}))});d=y({},this.a.fieldsObj,z(b,this.a.attributePrefix)); this.f.send("event",x(e,d,this.f,this.a.hitFilter,b,a))}};Y.prototype.shouldTrackOutboundLink=function(a,b){a=a.getAttribute("href")||a.getAttribute("xlink:href");b=b(a);return b.hostname!=location.hostname&&"http"==b.protocol.slice(0,4)};Y.prototype.remove=function(){var a=this;Object.keys(this.b).forEach(function(b){a.b[b].j()})};F("outboundLinkTracker",Y);var Z=C(); function Qa(a,b){var c=this;I(a,G.$);document.visibilityState&&(this.a=y({sessionTimeout:Fa,visibleThreshold:5E3,sendInitialPageview:!1,fieldsObj:{}},b),this.b=a,this.g=document.visibilityState,this.m=null,this.o=!1,this.v=this.v.bind(this),this.s=this.s.bind(this),this.G=this.G.bind(this),this.N=this.N.bind(this),this.c=R(a.get("trackingId"),"plugins/page-visibility-tracker"),Ba(this.c,this.N),this.f=Ga(a,this.a.sessionTimeout,this.a.timeZone),v(a,"set",this.v),window.addEventListener("unload",this.G), document.addEventListener("visibilitychange",this.s),va(this.b,function(){if("visible"==document.visibilityState)c.a.sendInitialPageview&&(Ra(c,{ea:!0}),c.o=!0),c.c.set({time:+new Date,state:"visible",pageId:Z,sessionId:V(c.f)});else if(c.a.sendInitialPageview&&c.a.pageLoadsMetricIndex){var a={},a=(a.transport="beacon",a.eventCategory="Page Visibility",a.eventAction="page load",a.eventLabel="(not set)",a["metric"+c.a.pageLoadsMetricIndex]=1,a.nonInteraction=!0,a);c.b.send("event",x(a,c.a.fieldsObj, c.b,c.a.hitFilter))}}))}f=Qa.prototype; f.s=function(){var a=this;if("visible"==document.visibilityState||"hidden"==document.visibilityState){var b=Sa(this),c={time:+new Date,state:document.visibilityState,pageId:Z,sessionId:V(this.f)};"visible"==document.visibilityState&&this.a.sendInitialPageview&&!this.o&&(Ra(this),this.o=!0);"hidden"==document.visibilityState&&this.m&&clearTimeout(this.m);this.f.isExpired(b.sessionId)?(Ea(this.c),"hidden"==this.g&&"visible"==document.visibilityState&&(clearTimeout(this.m),this.m=setTimeout(function(){a.c.set(c); Ra(a,{hitTime:c.time})},this.a.visibleThreshold))):(b.pageId==Z&&"visible"==b.state&&Ta(this,b),this.c.set(c));this.g=document.visibilityState}};function Sa(a){var b=a.c.get();"visible"==a.g&&"hidden"==b.state&&b.pageId!=Z&&(b.state="visible",b.pageId=Z,a.c.set(b));return b} function Ta(a,b,c){c=(c?c:{}).hitTime;var d={hitTime:c},d=(d?d:{}).hitTime;(b=b.time?(d||+new Date)-b.time:0)&&b>=a.a.visibleThreshold&&(b=Math.round(b/1E3),d={transport:"beacon",nonInteraction:!0,eventCategory:"Page Visibility",eventAction:"track",eventValue:b,eventLabel:"(not set)"},c&&(d.queueTime=+new Date-c),a.a.visibleMetricIndex&&(d["metric"+a.a.visibleMetricIndex]=b),a.b.send("event",x(d,a.a.fieldsObj,a.b,a.a.hitFilter)))} function Ra(a,b){var c=b?b:{};b=c.hitTime;var c=c.ea,d={transport:"beacon"};b&&(d.queueTime=+new Date-b);c&&a.a.pageLoadsMetricIndex&&(d["metric"+a.a.pageLoadsMetricIndex]=1);a.b.send("pageview",x(d,a.a.fieldsObj,a.b,a.a.hitFilter))}f.v=function(a){var b=this;return function(c,d){var e={},e=B(c)?c:(e[c]=d,e);e.page&&e.page!==b.b.get("page")&&"visible"==b.g&&b.s();a(c,d)}};f.N=function(a,b){a.time!=b.time&&(b.pageId!=Z||"visible"!=b.state||this.f.isExpired(b.sessionId)||Ta(this,b,{hitTime:a.time}))}; f.G=function(){"hidden"!=this.g&&this.s()};f.remove=function(){this.c.j();this.f.j();w(this.b,"set",this.v);window.removeEventListener("unload",this.G);document.removeEventListener("visibilitychange",this.s)};F("pageVisibilityTracker",Qa); function Ua(a,b){I(a,G.aa);window.addEventListener&&(this.a=y({fieldsObj:{},hitFilter:null},b),this.b=a,this.u=this.u.bind(this),this.J=this.J.bind(this),this.D=this.D.bind(this),this.A=this.A.bind(this),this.B=this.B.bind(this),this.F=this.F.bind(this),"complete"!=document.readyState?window.addEventListener("load",this.u):this.u())}f=Ua.prototype; f.u=function(){if(window.FB)try{window.FB.Event.subscribe("edge.create",this.B),window.FB.Event.subscribe("edge.remove",this.F)}catch(a){}window.twttr&&this.J()};f.J=function(){var a=this;try{window.twttr.ready(function(){window.twttr.events.bind("tweet",a.D);window.twttr.events.bind("follow",a.A)})}catch(b){}};function Va(a){try{window.twttr.ready(function(){window.twttr.events.unbind("tweet",a.D);window.twttr.events.unbind("follow",a.A)})}catch(b){}} f.D=function(a){if("tweet"==a.region){var b={transport:"beacon",socialNetwork:"Twitter",socialAction:"tweet",socialTarget:a.data.url||a.target.getAttribute("data-url")||location.href};this.b.send("social",x(b,this.a.fieldsObj,this.b,this.a.hitFilter,a.target,a))}}; f.A=function(a){if("follow"==a.region){var b={transport:"beacon",socialNetwork:"Twitter",socialAction:"follow",socialTarget:a.data.screen_name||a.target.getAttribute("data-screen-name")};this.b.send("social",x(b,this.a.fieldsObj,this.b,this.a.hitFilter,a.target,a))}};f.B=function(a){this.b.send("social",x({transport:"beacon",socialNetwork:"Facebook",socialAction:"like",socialTarget:a},this.a.fieldsObj,this.b,this.a.hitFilter))}; f.F=function(a){this.b.send("social",x({transport:"beacon",socialNetwork:"Facebook",socialAction:"unlike",socialTarget:a},this.a.fieldsObj,this.b,this.a.hitFilter))};f.remove=function(){window.removeEventListener("load",this.u);try{window.FB.Event.unsubscribe("edge.create",this.B),window.FB.Event.unsubscribe("edge.remove",this.F)}catch(a){}Va(this)};F("socialWidgetTracker",Ua); function Wa(a,b){I(a,G.ba);history.pushState&&window.addEventListener&&(this.a=y({shouldTrackUrlChange:this.shouldTrackUrlChange,trackReplaceState:!1,fieldsObj:{},hitFilter:null},b),this.b=a,this.c=location.pathname+location.search,this.H=this.H.bind(this),this.I=this.I.bind(this),this.C=this.C.bind(this),v(history,"pushState",this.H),v(history,"replaceState",this.I),window.addEventListener("popstate",this.C))}f=Wa.prototype; f.H=function(a){var b=this;return function(c){for(var d=[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];a.apply(null,[].concat(m(d)));Xa(b,!0)}};f.I=function(a){var b=this;return function(c){for(var d=[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];a.apply(null,[].concat(m(d)));Xa(b,!1)}};f.C=function(){Xa(this,!0)}; function Xa(a,b){setTimeout(function(){var c=a.c,d=location.pathname+location.search;c!=d&&a.a.shouldTrackUrlChange.call(a,d,c)&&(a.c=d,a.b.set({page:d,title:document.title}),(b||a.a.trackReplaceState)&&a.b.send("pageview",x({transport:"beacon"},a.a.fieldsObj,a.b,a.a.hitFilter)))},0)}f.shouldTrackUrlChange=function(a,b){return!(!a||!b)};f.remove=function(){w(history,"pushState",this.H);w(history,"replaceState",this.I);window.removeEventListener("popstate",this.C)};F("urlChangeTracker",Wa);})(); //# sourceMappingURL=autotrack.js.map ga('blogger.require', 'outboundLinkTracker'); //]]> </script> <script type="text/javascript" src="https://www.blogger.com/static/v1/widgets/2725212210-widgets.js"></script> <script type='text/javascript'> window['__wavt'] = 'AOuZoY59PJnh81MN_NASCFArSOMYevwfPw:1740975480257';_WidgetManager._Init('//www.blogger.com/rearrange?blogID\x3d8698702854482141883','//opensource.googleblog.com/2018/08/','8698702854482141883'); _WidgetManager._SetDataContext([{'name': 'blog', 'data': {'blogId': '8698702854482141883', 'title': 'Google Open Source Blog', 'url': 'https://opensource.googleblog.com/2018/08/', 'canonicalUrl': 'https://opensource.googleblog.com/2018/08/', 'homepageUrl': 'https://opensource.googleblog.com/', 'searchUrl': 'https://opensource.googleblog.com/search', 'canonicalHomepageUrl': 'https://opensource.googleblog.com/', 'blogspotFaviconUrl': 'https://opensource.googleblog.com/favicon.ico', 'bloggerUrl': 'https://www.blogger.com', 'hasCustomDomain': true, 'httpsEnabled': true, 'enabledCommentProfileImages': false, 'gPlusViewType': 'FILTERED_POSTMOD', 'adultContent': false, 'analyticsAccountNumber': 'UA-53341410-4', 'encoding': 'UTF-8', 'locale': 'en', 'localeUnderscoreDelimited': 'en', 'languageDirection': 'ltr', 'isPrivate': false, 'isMobile': false, 'isMobileRequest': false, 'mobileClass': '', 'isPrivateBlog': false, 'isDynamicViewsAvailable': true, 'feedLinks': '\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Google Open Source Blog - Atom\x22 href\x3d\x22https://opensource.googleblog.com/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22Google Open Source Blog - RSS\x22 href\x3d\x22https://opensource.googleblog.com/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Google Open Source Blog - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/8698702854482141883/posts/default\x22 /\x3e\n', 'meTag': '', 'adsenseHostId': 'ca-host-pub-1556223355139109', 'adsenseHasAds': false, 'adsenseAutoAds': false, 'boqCommentIframeForm': true, 'loginRedirectParam': '', 'view': '', 'dynamicViewsCommentsSrc': '//www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js', 'dynamicViewsScriptSrc': '//www.blogblog.com/dynamicviews/dbeedc0fc9862cb8', 'plusOneApiSrc': 'https://apis.google.com/js/platform.js', 'disableGComments': true, 'interstitialAccepted': false, 'sharing': {'platforms': [{'name': 'Get link', 'key': 'link', 'shareMessage': 'Get link', 'target': ''}, {'name': 'Facebook', 'key': 'facebook', 'shareMessage': 'Share to Facebook', 'target': 'facebook'}, {'name': 'BlogThis!', 'key': 'blogThis', 'shareMessage': 'BlogThis!', 'target': 'blog'}, {'name': 'X', 'key': 'twitter', 'shareMessage': 'Share to X', 'target': 'twitter'}, {'name': 'Pinterest', 'key': 'pinterest', 'shareMessage': 'Share to Pinterest', 'target': 'pinterest'}, {'name': 'Email', 'key': 'email', 'shareMessage': 'Email', 'target': 'email'}], 'disableGooglePlus': true, 'googlePlusShareButtonWidth': 0, 'googlePlusBootstrap': '\x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en\x27};\x3c/script\x3e'}, 'hasCustomJumpLinkMessage': false, 'jumpLinkMessage': 'Read more', 'pageType': 'archive', 'pageName': 'August 2018', 'pageTitle': 'Google Open Source Blog: August 2018', 'metaDescription': ''}}, {'name': 'features', 'data': {}}, {'name': 'messages', 'data': {'edit': 'Edit', 'linkCopiedToClipboard': 'Link copied to clipboard!', 'ok': 'Ok', 'postLink': 'Post Link'}}, {'name': 'template', 'data': {'name': 'custom', 'localizedName': 'Custom', 'isResponsive': false, 'isAlternateRendering': false, 'isCustom': true}}, {'name': 'view', 'data': {'classic': {'name': 'classic', 'url': '?view\x3dclassic'}, 'flipcard': {'name': 'flipcard', 'url': '?view\x3dflipcard'}, 'magazine': {'name': 'magazine', 'url': '?view\x3dmagazine'}, 'mosaic': {'name': 'mosaic', 'url': '?view\x3dmosaic'}, 'sidebar': {'name': 'sidebar', 'url': '?view\x3dsidebar'}, 'snapshot': {'name': 'snapshot', 'url': '?view\x3dsnapshot'}, 'timeslide': {'name': 'timeslide', 'url': '?view\x3dtimeslide'}, 'isMobile': false, 'title': 'Google Open Source Blog', 'description': '', 'url': 'https://opensource.googleblog.com/2018/08/', 'type': 'feed', 'isSingleItem': false, 'isMultipleItems': true, 'isError': false, 'isPage': false, 'isPost': false, 'isHomepage': false, 'isArchive': true, 'isLabelSearch': false, 'archive': {'year': 2018, 'month': 8, 'rangeMessage': 'Showing posts from August, 2018'}}}]); _WidgetManager._RegisterWidget('_HeaderView', new _WidgetInfo('Header1', 'header', document.getElementById('Header1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogView', new _WidgetInfo('Blog1', 'main', document.getElementById('Blog1'), {'cmtInteractionsEnabled': false}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML4', 'sidebar-right-1', document.getElementById('HTML4'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_PopularPostsView', new _WidgetInfo('PopularPosts1', 'sidebar-right-1', document.getElementById('PopularPosts1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogArchiveView', new _WidgetInfo('BlogArchive1', 'sidebar-right-1', document.getElementById('BlogArchive1'), {'languageDirection': 'ltr', 'loadingMessage': 'Loading\x26hellip;'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML3', 'sidebar-right-1', document.getElementById('HTML3'), {}, 'displayModeFull')); </script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10