cmd/golangorg: move blog from blog.golang.org to go.dev/blog

This is the first of a sequence of consolidations of web sites into
the single site go.dev. An accompanying blog post (next CL) will
explain the change.

The blog/_content tree moves to go.dev/_content/blog.
The *.article files were converted to *.md files using rsc.io/tmp/blog2md.
The old dot directives are now template function invocations,
so that blog content files are now exactly the same format and
semantics as regular site content files.

All the old blog redirects are carried forward, of course.

Also add exhaustive test that every .md file renders correctly.

Also rename rawhtml to raw, because it gets used for raw Markdown too.
The raw Markdown issue is working around a bigger problem
(html/template is not really right for Markdown) that we will have
to solve at some point, but not in this CL.

Change-Id: Ifa9b3b8d656a72af30d0d4e57e4c7bc8dacbc386
Reviewed-on: https://go-review.googlesource.com/c/website/+/342091
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
diff --git a/README.md b/README.md
index ec3d08e..39b303d 100644
--- a/README.md
+++ b/README.md
@@ -2,17 +2,18 @@
 
 [![Go Reference](https://pkg.go.dev/badge/golang.org/x/website.svg)](https://pkg.go.dev/golang.org/x/website)
 
-This repo holds content and serving programs for the golang.org web site.
+This repo holds content and serving programs for the golang.org and go.dev web sites.
 
-Content is in _content/. Server code is in cmd/ and internal/.
+Content is in _content/ (golang.org), go.dev/_content/ (go.dev), and tour/ (tour.golang.org).
+Server code is in cmd/ and internal/.
 
-To run the server to preview local content changes, use:
+To run the combined golang.org+go.dev server to preview local content changes, use:
 
 	go run ./cmd/golangorg
 
 The supporting programs cmd/admingolangorg and cmd/googlegolangorg
 are the servers for admin.golang.org and google.golang.org.
-(They do not use the _content/ directory.)
+(They do not use the _content/ directories.)
 
 Each command directory has its own README.md explaining deployment.
 
diff --git a/_content/ref/mod.md b/_content/ref/mod.md
index d8a78ae..8594378 100644
--- a/_content/ref/mod.md
+++ b/_content/ref/mod.md
@@ -1573,7 +1573,7 @@
 ```
 
 The `Module` struct has a `String` method that formats this line of output, so
-that the default format is equivalent to {{rawhtml "`-f '{{.String}}'`"}}.
+that the default format is equivalent to {{raw "`-f '{{.String}}'`"}}.
 
 Note that when a module has been replaced, its `Replace` field describes the
 replacement module module, and its `Dir` field is set to the replacement
@@ -2192,9 +2192,9 @@
   specific version. See [Versions](#versions) for syntax.
 * A semantic version prefix, such as `v1` or `v1.2`, which selects the highest
   available version with that prefix.
-* A semantic version comparison, such as {{rawhtml "`<v1.2.3` or `>=v1.5.6`"}}, which selects
+* A semantic version comparison, such as {{raw "`<v1.2.3` or `>=v1.5.6`"}}, which selects
   the nearest available version to the comparison target (the lowest version
-  for `>` and `>=`, and the highest version for {{rawhtml "`<` and `<=`"}}).
+  for `>` and `>=`, and the highest version for {{raw "`<` and `<=`"}}).
 * A revision identifier for the underlying source repository, such as a commit
   hash prefix, revision tag, or branch name. If the revision is tagged with a
   semantic version, this query selects that version. Otherwise, this query
@@ -2228,7 +2228,7 @@
 [Release versions](#glos-release-version) are preferred over pre-release
 versions. For example, if versions `v1.2.2` and `v1.2.3-pre` are available, the
 `latest` query will select `v1.2.2`, even though `v1.2.3-pre` is higher. The
-{{rawhtml "`<v1.2.4`"}} query would also select `v1.2.2`, even though `v1.2.3-pre` is closer
+{{raw "`<v1.2.4`"}} query would also select `v1.2.2`, even though `v1.2.3-pre` is closer
 to `v1.2.4`. If no release or pre-release version is available, the `latest`,
 `upgrade`, and `patch` queries will select a pseudo-version for the commit
 at the tip of the repository's default branch. Other queries will report
diff --git a/blog/.gcloudignore b/blog/.gcloudignore
deleted file mode 100644
index 7df1578..0000000
--- a/blog/.gcloudignore
+++ /dev/null
@@ -1 +0,0 @@
-.gcloudignore
diff --git a/blog/README.md b/blog/README.md
deleted file mode 100644
index bbba25c..0000000
--- a/blog/README.md
+++ /dev/null
@@ -1,54 +0,0 @@
-# Go Blog
-
-[![Go Reference](https://pkg.go.dev/badge/golang.org/x/website/blog.svg)](https://pkg.go.dev/golang.org/x/website/blog)
-
-This directory holds the Go Blog server code and content.
-
-## Download/Install
-
-The easiest way to install is to run `go get -u golang.org/x/website/blog`. You can also
-manually git clone the repository to \$GOPATH/src/golang.org/x/website.
-
-## Running Locally
-
-To run the blog server locally:
-
-```
-go run . -reload
-```
-
-and then visit [http://localhost:8080/](http://localhost:8080) in your browser.
-
-## Contributing
-
-Articles are written in the [x/tools/present][present] format.
-Articles on the blog should have broad interest to the Go community, and
-are mainly written by Go contributors. We encourage you to share your
-experiences using Go on your own website, and [to share them with the Go
-community][community]. [Hugo][hugo] is a static site server written in Go that
-makes it easy to write and share your stories.
-
-[present]: https://godoc.org/golang.org/x/tools/present
-[community]: https://golang.org/help/
-[hugo]: https://gohugo.io/
-
-## Report Issues / Send Patches
-
-This repository uses Gerrit for code changes. To learn how to submit changes to
-this repository, see https://golang.org/doc/contribute.html.
-
-The main issue tracker for the blog is located at
-https://github.com/golang/go/issues. Prefix your issue with "x/website/blog:" in the
-subject line, so it is easy to find.
-
-## Deploying
-
-Each time a CL is reviewed and submitted, the blog is automatically deployed to App Engine.
-If the CL is submitted with a Website-Publish +1 vote,
-the new deployment automatically becomes https://blog.golang.org/.
-Otherwise, the new deployment can be found in the
-[App Engine versions list](https://console.cloud.google.com/appengine/versions?project=golang-org&serviceId=blog) and verified and manually promoted.
-
-If the automatic deployment is not working, or to check on the status of a pending deployment,
-see the “website-redeploy-blog” trigger in the
-[Cloud Build console](https://console.cloud.google.com/cloud-build/builds?project=golang-org).
diff --git a/blog/_content/io2010.article b/blog/_content/io2010.article
deleted file mode 100644
index 7fb9484..0000000
--- a/blog/_content/io2010.article
+++ /dev/null
@@ -1,13 +0,0 @@
-# Go Programming session video from Google I/O
-6 Jun 2010
-Tags: video, talk
-Summary: A talk by Rob Pike and Russ Cox about Go, from Google I/O 2010.
-OldURL: /go-programming-session-video-from
-
-Andrew Gerrand
-
-##
-
-Below is the video of the talk given by Rob Pike and Russ Cox at Google I/O 2010.
-
-.iframe //www.youtube.com/embed/jgVhBThJdXc 304 540
diff --git a/blog/_static/fonts.css b/blog/_static/fonts.css
deleted file mode 100644
index 62ca66e..0000000
--- a/blog/_static/fonts.css
+++ /dev/null
@@ -1,69 +0,0 @@
-@font-face {
-	font-family: 'Go';
-	src: url('fonts/GoMedium-Italic.woff') format('woff');
-	font-weight: 500;
-	font-style: italic;
-}
-
-@font-face {
-	font-family: 'Go';
-	src: url('fonts/Go-Italic.woff') format('woff');
-	font-weight: normal;
-	font-style: italic;
-}
-
-@font-face {
-	font-family: 'Go';
-	src: url('fonts/Go-Bold.woff') format('woff');
-	font-weight: bold;
-	font-style: normal;
-}
-
-@font-face {
-	font-family: 'Go';
-	src: url('fonts/GoMedium.woff') format('woff');
-	font-weight: 500;
-	font-style: normal;
-}
-
-@font-face {
-	font-family: 'Go';
-	src: url('fonts/Go-BoldItalic.woff') format('woff');
-	font-weight: bold;
-	font-style: italic;
-}
-
-@font-face {
-	font-family: 'Go';
-	src: url('fonts/GoRegular.woff') format('woff');
-	font-weight: normal;
-	font-style: normal;
-}
-
-@font-face {
-	font-family: 'Go Mono';
-	src: url('fonts/GoMono-Bold.woff') format('woff');
-	font-weight: bold;
-	font-style: normal;
-}
-
-@font-face {
-	font-family: 'Go Mono';
-	src: url('fonts/GoMono.woff') format('woff');
-	font-weight: normal;
-	font-style: normal;
-}
-
-@font-face {
-	font-family: 'Go Mono';
-	src: url('fonts/GoMono-Italic.woff') format('woff');
-	font-weight: normal;
-	font-style: italic;
-}
-
-@font-face {
-	font-family: 'Go Mono';
-	src: url('fonts/GoMono-BoldItalic.woff') format('woff');
-	font-weight: bold;
-	font-style: italic;
-}
diff --git a/blog/_template/article.tmpl b/blog/_template/article.tmpl
deleted file mode 100644
index 2bb3b7b..0000000
--- a/blog/_template/article.tmpl
+++ /dev/null
@@ -1,15 +0,0 @@
-{{/* This file is combined with the root.tmpl to display a single article. */}}
-
-{{define "title"}}{{.Doc.Title}} - The Go Blog{{end}}
-{{define "content"}}
-	{{template "doc" .Doc}}
-	{{with .Doc.Related}}
-		<h2>Related articles</h2>
-		<ul>
-		{{range .}}
-			<li><a href="{{.Path}}">{{.Title}}</a></li>
-		{{end}}
-		</ul>
-	{{end}}
-{{end}}
-
diff --git a/blog/_template/doc.tmpl b/blog/_template/doc.tmpl
deleted file mode 100644
index 3289ce9..0000000
--- a/blog/_template/doc.tmpl
+++ /dev/null
@@ -1,85 +0,0 @@
-{{/* This doc template is given to the present tool to format articles.  */}}
-
-{{define "root"}}
-  {{with .Subtitle}}<h2>{{.}}</h2>{{end}}
-  {{if .Doc | sectioned}}
-    {{range .Sections}}
-      {{elem $.Template .}}
-    {{end}}
-  {{else}}
-    {{with index .Sections 0}}
-      {{range .Elem}}
-        {{elem $.Template .}}
-      {{end}}
-    {{end}}
-  {{end}}
-{{end}}
-
-{{define "TOC"}}
-  <ul>
-  {{range .}}
-    <li><a href="#TOC_{{.FormattedNumber}}">{{.Title}}</a></li>
-    {{with .Sections}}{{template "TOC" .}}{{end}}
-  {{end}}
-  </ul>
-{{end}}
-
-{{define "newline"}}
-{{/* No automatic line break. Paragraphs are free-form. */}}
-{{end}}
-
-{{define "section"}}
-  {{$name := printf "TOC_%s" .FormattedNumber}}
-  {{with .ID}}{{$name = .}}{{end}}
-  <a {{with .ID}}name="{{.}}" {{end}}class="head" href="#{{$name}}"><h4 id="TOC_{{.FormattedNumber}}">{{.Title}}</h4></a>
-  {{range .Elem}}{{elem $.Template .}}{{end}}
-{{end}}
-
-{{define "list"}}
-  <ul>
-  {{range .Bullet}}
-    <li>{{style .}}</li>
-  {{end}}
-  </ul>
-{{end}}
-
-{{define "text"}}
-  {{if .Pre}}
-  <div class="code"><pre>{{range .Lines}}{{.}}{{end}}</pre></div>
-  {{else}}
-  <p>
-    {{range $i, $l := .Lines}}{{if $i}}{{template "newline"}}
-    {{end}}{{style $l}}{{end}}
-  </p>
-  {{end}}
-{{end}}
-
-{{define "code"}}
-  {{if .Play}}
-	<div class="playground">{{.Text}}</div>
-  {{else}}
-	<div class="code">{{.Text}}</div>
-  {{end}}
-{{end}}
-
-{{define "image"}}
-<div class="image">
-  <img src="{{.URL}}"{{with .Height}} height="{{.}}"{{end}}{{with .Width}} width="{{.}}"{{end}} alt="">
-</div>
-{{end}}
-
-{{define "caption"}}
-<div class="image">
-  <figcaption>{{style .Text}}</figcaption>
-</div>
-{{end}}
-
-{{define "iframe"}}
-<div class="iframe">
-  <iframe src="{{.URL}}"{{with .Height}} height="{{.}}"{{end}}{{with .Width}} width="{{.}}"{{end}} frameborder="0" allowfullscreen mozallowfullscreen webkitallowfullscreen></iframe>
-</div>
-{{end}}
-
-{{define "link"}}<p class="link"><a href="{{.URL}}" target="_blank" rel="noopener">{{style .Label}}</a></p>{{end}}
-
-{{define "html"}}{{.HTML}}{{end}}
diff --git a/blog/_template/home.tmpl b/blog/_template/home.tmpl
deleted file mode 100644
index 13aaef2..0000000
--- a/blog/_template/home.tmpl
+++ /dev/null
@@ -1,9 +0,0 @@
-{{/* This file is combined with the root.tmpl to display the blog home page. */}}
-
-{{define "title"}}The Go Programming Language Blog{{end}}
-{{define "content"}}
-	{{range .Data}}
-		{{template "doc" .}}
-	{{end}}
-	<p>See the <a href="{{.BasePath}}/index">index</a> for more articles.
-{{end}}
diff --git a/blog/_template/index.tmpl b/blog/_template/index.tmpl
deleted file mode 100644
index 512ef72..0000000
--- a/blog/_template/index.tmpl
+++ /dev/null
@@ -1,16 +0,0 @@
-{{/* This file is combined with the root.tmpl to display the blog index. */}}
-
-{{define "title"}}Article index - The Go Blog{{end}}
-{{define "content"}}
-
-  <h1 class="title">Article index</h1>
-
-  {{range .Data}}
-  <p class="blogtitle">
-    <a href="{{.Path}}">{{.Title}}</a>, <span class="date">{{.Time.Format "2 January 2006"}}</span><br>
-    <span class="author">{{with .Authors}}{{authors .}}<br>{{end}}</span>
-    {{with .Tags}}<span class="tags">{{range .}}{{.}} {{end}}</span>{{end}}
-  </p>
-  {{end}}
-
-{{end}}
diff --git a/blog/_template/root.tmpl b/blog/_template/root.tmpl
deleted file mode 100644
index 6000c1a..0000000
--- a/blog/_template/root.tmpl
+++ /dev/null
@@ -1,210 +0,0 @@
-{{/* This template is combined with other templates to render blog pages. */}}
-
-{{define "root"}}
-<!DOCTYPE html>
-<html lang="en">
-{{.AnalyticsHTML}}<meta charset="utf-8">
-<meta name="viewport" content="width=device-width, initial-scale=1">
-<meta name="theme-color" content="#00ADD8">
-<meta name="description" content="Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.">
-<title>{{template "title" .}}</title>
-<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Work+Sans:600|Roboto:400,700|Source+Code+Pro">
-<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Product+Sans&text=Supported%20by%20Google&display=swap">
-<link rel="stylesheet" href="/lib/godoc/style.css">
-<link rel="stylesheet" href="/fonts.css">
-<link rel="alternate" type="application/atom+xml" title="blog.golang.org - Atom Feed" href="https://blog.golang.org/feed.atom" />
-<script>window.initFuncs = [];</script>
-<style>
-  h1,
-  h2,
-  h3,
-  h4,
-  h5,
-  h6 {
-    font-family: 'Work Sans', sans-serif;
-    font-weight: 600;
-  }
-  h2 { /* Reset from style.js in x/website */
-    background: none;
-    clear: none;
-    font-size: 1.5em;
-    font-weight: 600;
-    line-height: inherit;
-    overflow-wrap: normal;
-    padding: 0;
-  }
-  a.head {
-    color: black;
-    text-decoration: none !important;
-  }
-  a.head:hover {
-    text-decoration: underline;
-  }
-  @media print {
-    #sidebar { display: none; }
-  }
-  #sidebar {
-    float: right;
-    padding-left: 20px;
-    width: 40%;
-    max-width: 250px;
-    background: #f8f9f9;
-    margin: 20px 0 20px 20px;
-  }
-  #sidebar h2 {
-    font-size: 1rem;
-  }
-  #sidebar ul {
-    padding: 0;
-  }
-  #sidebar li {
-    list-style-type: none;
-  }
-  #content .author {
-    font-style: italic;
-  }
-  #content .article {
-    margin-bottom: 50px;
-  }
-  #content .date {
-    color: #6e7072;
-  }
-  #content .tags {
-    color: #999;
-    font-size: smaller;
-  }
-  #content .iframe, #content .image {
-    margin: 20px;
-  }
-  #content .title {
-    margin: 20px 0;
-  }
-  #content img {
-    max-width: 100%;
-  }
-  .article[data-slug='/go-fonts'] {
-    font-family: Go, sans-serif;
-  }
-  .article[data-slug='/go-fonts'] pre,
-  .article[data-slug='/go-fonts'] code {
-    font-family: 'Go Mono', monospace;
-  }
-</style>
-<body class="Site">
-  <header class="Header js-header">
-    <div class="Header-banner">
-      Black Lives Matter.
-      <a href="https://support.eji.org/give/153413/#!/donation/checkout"
-        target="_blank"
-        rel="noopener">Support the Equal Justice Initiative.</a>
-    </div>
-    <nav class="Header-nav">
-      <a href="{{.GodocURL}}"><img class="Header-logo" src="/lib/godoc/images/go-logo-blue.svg" alt="Go"></a>
-      <button class="Header-menuButton js-headerMenuButton" aria-label="Main menu" aria-expanded="false">
-        <div class="Header-menuButtonInner">
-      </button>
-      <ul class="Header-menu">
-        <li class="Header-menuItem"><a href="{{.GodocURL}}/doc/">Documents</a></li>
-        <li class="Header-menuItem"><a href="{{.GodocURL}}/pkg/">Packages</a></li>
-        <li class="Header-menuItem"><a href="{{.GodocURL}}/project/">The Project</a></li>
-        <li class="Header-menuItem"><a href="{{.GodocURL}}/help/">Help</a></li>
-        <li class="Header-menuItem"><a href="{{.BasePath}}/">Blog</a></li>
-        <li class="Header-menuItem"><a href="https://play.golang.org/">Play</a></li>
-      </ul>
-    </nav>
-  </header>
-
-  <main class="Site-content" id="page">
-    <div class="container">
-      <aside id="sidebar">
-        {{with .Doc}}
-          {{with .Newer}}
-            <h2>Next article</h2>
-            <p><a href="{{.Path}}">{{.Title}}</a></p>
-          {{end}}
-
-          {{with .Older}}
-            <h2>Previous article</h2>
-            <p><a href="{{.Path}}">{{.Title}}</a></p>
-          {{end}}
-        {{end}}
-
-        <h2>Links</h2>
-        <ul>
-          <li><a href='//golang.org/'>golang.org</a></li>
-          <li><a href='//golang.org/doc/install.html'>Install Go</a></li>
-          <li><a href='//tour.golang.org/'>A Tour of Go</a></li>
-          <li><a href='//golang.org/doc/'>Go Documentation</a></li>
-          <li><a href='//groups.google.com/group/golang-nuts'>Go Mailing List</a></li>
-          <li><a href='//twitter.com/golang'>Go on Twitter</a></li>
-        </ul>
-
-        <p><a href="{{.BasePath}}/index">Blog index</a></p>
-      </aside><!-- #sidebar -->
-
-      <div id="content">
-        <h1><a href="{{.BasePath}}/">The Go Blog</a></h1>
-        {{template "content" .}}
-      </div><!-- #content -->
-
-    </div><!-- .container -->
-  </main><!-- #page -->
-
-  <footer>
-    <div class="Footer">
-      <img class="Footer-gopher" src="/lib/godoc/images/footer-gopher.jpg" alt="The Go Gopher">
-      <ul class="Footer-links">
-        <li class="Footer-link"><a href="{{.GodocURL}}/doc/copyright.html">Copyright</a></li>
-        <li class="Footer-link"><a href="{{.GodocURL}}/doc/tos.html">Terms of Service</a></li>
-        <li class="Footer-link"><a href="http://www.google.com/intl/en/policies/privacy/">Privacy Policy</a></li>
-        <li class="Footer-link"><a href="http://golang.org/issues/new?title=x/blog:" target="_blank" rel="noopener">Report issue</a></li>
-      </ul>
-      <a class="Footer-supportedBy" href="https://google.com">Supported by Google</a>
-    </div>
-  </footer>
-
-  <script src="/lib/godoc/jquery.js"></script>
-  <script src="/lib/godoc/playground.js"></script>
-  <script src="/lib/godoc/play.js"></script>
-  <script src="/lib/godoc/godocs.js"></script>
-  <script>
-  $(function() {
-    // Insert line numbers for all playground elements.
-    $('.playground > pre.numbers, .code > pre.numbers').each(function() {
-      var $spans = $(this).find('> span');
-
-      // Compute width of number column (including trailing space).
-      var max = 0;
-      $spans.each(function() {
-        var n = $(this).attr('num')*1;
-        if (n > max) max = n;
-      });
-      var width = 2;
-      while (max > 10) {
-        max = max / 10;
-        width++;
-      }
-
-      // Insert line numbers with space padding.
-      $spans.each(function() {
-        var n = $(this).attr('num')+' ';
-        while (n.length < width) n = ' '+n;
-        $('<span class="number">').text(n).insertBefore(this);
-      });
-    });
-
-    initPlayground(new HTTPTransport());
-  });
-  </script>
-{{end}}
-
-{{define "doc"}}
-  <div class="article" data-slug="{{.Path}}">
-    <h2 class="title"><a href="{{.Path}}">{{.Title}}</a></h2>
-    <p class="author">
-    {{with .Authors}}{{authors .}}<br>{{end}}
-    {{.Time.Format "2 January 2006"}}
-    </p>
-    {{.HTML}}
-  </div>
-{{end}}
diff --git a/blog/app.yaml b/blog/app.yaml
deleted file mode 100644
index a0d983c..0000000
--- a/blog/app.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-# This app is deployed via Cloud Build as directed by cloudbuild.yaml.
-# Do not deploy directly.
-
-service: blog
-runtime: go115
-main: ./blog
-
-handlers:
-- url: /.*
-  script: auto
-  secure: always
-
-env_variables:
-  BLOG_ANALYTICS: |
-    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-11222381-3"></script>
-    <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag("js", new Date());
-    gtag("config", "UA-11222381-3");
-    gtag("config", "UA-49880327-6");
-    </script>
diff --git a/blog/blog.go b/blog/blog.go
deleted file mode 100644
index 5535e5a..0000000
--- a/blog/blog.go
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Command blog is a web server for the Go blog that can run on App Engine or
-// as a stand-alone HTTP server.
-package main
-
-import (
-	"flag"
-	"html/template"
-	"log"
-	"net"
-	"net/http"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"golang.org/x/tools/blog"
-	_ "golang.org/x/tools/playground"
-	"golang.org/x/website"
-	"golang.org/x/website/internal/backport/httpfs"
-	"golang.org/x/website/internal/webtest"
-)
-
-var (
-	httpAddr = flag.String("http", "localhost:8080", "HTTP listen address")
-	reload   = flag.Bool("reload", false, "reload content on each page load")
-
-	runningOnAppEngine = os.Getenv("GAE_ENV") != ""
-	blogRoot           = "./"
-)
-
-const hostname = "blog.golang.org" // default hostname for blog server
-
-var config = blog.Config{
-	Hostname:      hostname,
-	BaseURL:       "https://" + hostname,
-	GodocURL:      "https://golang.org",
-	HomeArticles:  5,  // articles to display on the home page
-	FeedArticles:  10, // articles to include in Atom and JSON feeds
-	PlayEnabled:   true,
-	FeedTitle:     "The Go Programming Language Blog",
-	ContentPath:   "_content/",
-	TemplatePath:  "_template/",
-	AnalyticsHTML: template.HTML(os.Getenv("BLOG_ANALYTICS")),
-}
-
-func main() {
-	if runningOnAppEngine {
-		port := os.Getenv("PORT")
-		if port == "" {
-			port = "8080"
-		}
-		*httpAddr = ":" + port
-	}
-
-	flag.Parse()
-
-	if _, err := os.Stat("blog/_content/10years"); err == nil {
-		blogRoot = "blog/"
-	}
-	config.ContentPath = blogRoot + config.ContentPath
-	config.TemplatePath = blogRoot + config.TemplatePath
-
-	h, err := blogHandler()
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	h = webtest.HandlerWithCheck(h, "/_readycheck",
-		filepath.Join(blogRoot, "testdata/*.txt"))
-
-	http.Handle("/", h)
-
-	ln, err := net.Listen("tcp", *httpAddr)
-	if err != nil {
-		log.Fatal(err)
-	}
-	log.Println("Listening on addr", *httpAddr)
-	log.Fatal(http.Serve(ln, nil))
-}
-
-func blogHandler() (http.Handler, error) {
-	var h http.Handler
-	if *reload {
-		h = http.HandlerFunc(reloadingBlogServer)
-	} else {
-		s, err := blog.NewServer(config)
-		if err != nil {
-			return nil, err
-		}
-		h = s
-	}
-	h = maybeStatic(h)
-
-	mux := http.NewServeMux()
-	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-		if runningOnAppEngine {
-			w.Header().Set("Strict-Transport-Security", "max-age=31536000; preload")
-		}
-		h.ServeHTTP(w, r)
-	})
-
-	// Redirect "/blog/" to "/", because the menu bar link is to "/blog/"
-	// but we're serving from the root.
-	redirect := func(w http.ResponseWriter, r *http.Request) {
-		http.Redirect(w, r, "/", http.StatusFound)
-	}
-	mux.HandleFunc("/blog", redirect)
-	mux.HandleFunc("/blog/", redirect)
-
-	// Keep these static file handlers in sync with app.yaml.
-	static := http.FileServer(http.Dir(blogRoot + "static"))
-	mux.Handle("/favicon.ico", static)
-	mux.Handle("/fonts.css", static)
-	mux.Handle("/fonts/", static)
-	mux.Handle("/lib/godoc/", http.FileServer(httpfs.FS(website.Content)))
-
-	// Redirects in redirect.go.
-	for old, new := range redirects {
-		new := new // for closure
-		mux.HandleFunc(old, func(w http.ResponseWriter, r *http.Request) {
-			http.Redirect(w, r, "/"+new, http.StatusMovedPermanently)
-		})
-	}
-
-	return mux, nil
-}
-
-// maybeStatic serves from _static if possible,
-// or else defers to the fallback handler.
-func maybeStatic(fallback http.Handler) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		p := r.URL.Path
-		if strings.Contains(p, ".") && !strings.HasSuffix(p, "/") {
-			f := filepath.Join("_static", p)
-			if _, err := os.Stat(f); err == nil {
-				http.ServeFile(w, r, f)
-				return
-			}
-		}
-		fallback.ServeHTTP(w, r)
-	}
-}
-
-// reloadingBlogServer is an handler that restarts the blog server on each page
-// view. Inefficient; don't enable by default. Handy when editing blog content.
-func reloadingBlogServer(w http.ResponseWriter, r *http.Request) {
-	s, err := blog.NewServer(config)
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	s.ServeHTTP(w, r)
-}
diff --git a/blog/blog_test.go b/blog/blog_test.go
deleted file mode 100644
index 371d682..0000000
--- a/blog/blog_test.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-	"testing"
-
-	"golang.org/x/website/internal/webtest"
-)
-
-func TestServer(t *testing.T) {
-	h, err := blogHandler()
-	if err != nil {
-		t.Fatal(err)
-	}
-	webtest.TestHandler(t, "testdata/blog.txt", h)
-}
diff --git a/blog/cloudbuild.yaml b/blog/cloudbuild.yaml
deleted file mode 100644
index dbf45e9..0000000
--- a/blog/cloudbuild.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-# This Cloud Build file is run automatically when commits land in the website repo.
-# See https://console.cloud.google.com/cloud-build/triggers?project=golang-org.
-# Do not run directly.
-
-steps:
-  - name: golang
-    args: ["go", "test", "./..."]
-    dir: blog
-  - name: gcr.io/cloud-builders/gcloud
-    entrypoint: bash
-    args: ["./go-app-deploy.sh", "blog/app.yaml"]
-  - name: golang
-    args: [
-      "go", "run", "./cmd/versionprune", "--dry_run=false",
-      "--project=$PROJECT_ID", "--service=blog",
-    ]
-    dir: go.dev
-
-options:
-  machineType: E2_HIGHCPU_8
diff --git a/blog/testdata/blog.txt b/blog/testdata/blog.txt
deleted file mode 100644
index 2121356..0000000
--- a/blog/testdata/blog.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-GET /
-body contains The Go Programming Language Blog
-header Content-Type == text/html; charset=utf-8
-
-GET /2010/08/defer-panic-and-recover.html
-redirect == /defer-panic-and-recover
diff --git a/cmd/golangorg/csp.go b/cmd/golangorg/csp.go
index e67f07f..af204f5 100644
--- a/cmd/golangorg/csp.go
+++ b/cmd/golangorg/csp.go
@@ -42,6 +42,7 @@
 
 var csp = map[string][]string{
 	"connect-src": {
+		"'self'",
 		"https://golang.org",
 		"www.google-analytics.com",
 		"stats.g.doubleclick.net",
diff --git a/cmd/golangorg/godev.go b/cmd/golangorg/godev.go
index ca280d2..8fc9275 100644
--- a/cmd/golangorg/godev.go
+++ b/cmd/golangorg/godev.go
@@ -6,22 +6,16 @@
 
 import (
 	"net/http"
-	"net/url"
 	"sort"
 	"strings"
 	"time"
 
 	"golang.org/x/website/internal/backport/html/template"
 	"golang.org/x/website/internal/backport/osfs"
+	"golang.org/x/website/internal/blog"
 	"golang.org/x/website/internal/web"
 )
 
-var discoveryHosts = map[string]string{
-	"":               "pkg.go.dev",
-	"dev.go.dev":     "dev-pkg.go.dev",
-	"staging.go.dev": "staging-pkg.go.dev",
-}
-
 func godevHandler(dir string) (http.Handler, error) {
 	godev := web.NewSite(osfs.DirFS(dir))
 	godev.Funcs(template.FuncMap{
@@ -30,8 +24,12 @@
 	})
 	mux := http.NewServeMux()
 	mux.Handle("/", addCSP(godev))
-	mux.Handle("/explore/", http.StripPrefix("/explore/", redirectHosts(discoveryHosts)))
-	mux.Handle("learn.go.dev/", http.HandlerFunc(redirectLearn))
+	mux.Handle("/explore/", http.StripPrefix("/explore/", redirectPrefix("https://pkg.go.dev/")))
+
+	if err := blog.RegisterFeeds(mux, "", godev); err != nil {
+		return nil, err
+	}
+
 	return mux, nil
 }
 
@@ -79,22 +77,3 @@
 	}
 	return u[:1+i+1]
 }
-
-func redirectLearn(w http.ResponseWriter, r *http.Request) {
-	http.Redirect(w, r, "https://go.dev/learn/"+strings.TrimPrefix(r.URL.Path, "/"), http.StatusMovedPermanently)
-}
-
-type redirectHosts map[string]string
-
-func (rh redirectHosts) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	u := &url.URL{Scheme: "https", Path: r.URL.Path, RawQuery: r.URL.RawQuery}
-	if h, ok := rh[r.Host]; ok {
-		u.Host = h
-	} else if h, ok := rh[""]; ok {
-		u.Host = h
-	} else {
-		http.NotFound(w, r)
-		return
-	}
-	http.Redirect(w, r, u.String(), http.StatusFound)
-}
diff --git a/cmd/golangorg/godev_test.go b/cmd/golangorg/godev_test.go
index 962c1af..19ebaad 100644
--- a/cmd/golangorg/godev_test.go
+++ b/cmd/golangorg/godev_test.go
@@ -6,71 +6,11 @@
 
 import (
 	"bytes"
-	"net/http"
 	"net/http/httptest"
 	"strings"
 	"testing"
 )
 
-var testHosts = map[string]string{
-	"":                     "foo.example.test",
-	"dev.example.test":     "foo-dev.example.test",
-	"staging.example.test": "foo-staging.example.test",
-}
-
-func TestRedirect(t *testing.T) {
-	tests := []struct {
-		desc     string
-		target   string
-		hosts    map[string]string
-		want     string
-		wantCode int
-	}{
-		{
-			desc:     "basic redirect",
-			target:   "/",
-			hosts:    testHosts,
-			want:     "https://foo.example.test/",
-			wantCode: http.StatusFound,
-		},
-		{
-			desc:     "redirect keeps query and path",
-			target:   "/github.com/golang/glog?tab=overview",
-			hosts:    testHosts,
-			want:     "https://foo.example.test/github.com/golang/glog?tab=overview",
-			wantCode: http.StatusFound,
-		},
-		{
-			desc:     "redirects to the correct host",
-			target:   "https://dev.example.test/",
-			hosts:    testHosts,
-			want:     "https://foo-dev.example.test/",
-			wantCode: http.StatusFound,
-		},
-		{
-			desc:     "renders 404 if hosts are missing",
-			target:   "https://dev.example.test/",
-			hosts:    nil,
-			wantCode: http.StatusNotFound,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.desc, func(t *testing.T) {
-			req := httptest.NewRequest("GET", tt.target, nil)
-			w := httptest.NewRecorder()
-			redirectHosts(tt.hosts).ServeHTTP(w, req)
-			resp := w.Result()
-			if resp.StatusCode != tt.wantCode {
-				t.Errorf("w.Result().StatusCode = %v, wanted %v", resp.StatusCode, tt.wantCode)
-			}
-			l, err := resp.Location()
-			if resp.StatusCode == http.StatusFound && (l == nil || l.String() != tt.want || err != nil) {
-				t.Errorf("resp.Location() = %v, %v, wanted %v, no error", l, err, tt.want)
-			}
-		})
-	}
-}
-
 var siteTests = []struct {
 	target string
 	want   []string
diff --git a/cmd/golangorg/server.go b/cmd/golangorg/server.go
index 6f61dcb..838eab0 100644
--- a/cmd/golangorg/server.go
+++ b/cmd/golangorg/server.go
@@ -55,6 +55,8 @@
 
 	runningOnAppEngine = os.Getenv("PORT") != ""
 
+	tipFlag = flag.Bool("tip", runningOnAppEngine, "load git content for tip.golang.org")
+
 	googleAnalytics string
 )
 
@@ -123,8 +125,6 @@
 	}
 }
 
-var isTestBinary = false
-
 // NewHandler returns the http.Handler for the web site,
 // given the directory where the content can be found
 // (can be "", in which case an internal copy is used)
@@ -176,7 +176,7 @@
 	// which broke the redirect.
 	mux.Handle("m.golang.org/", http.RedirectHandler("https://mail.google.com/a/golang.org/", http.StatusMovedPermanently))
 
-	if !isTestBinary {
+	if *tipFlag {
 		go watchTip(&tipGoroot)
 	}
 
@@ -206,7 +206,9 @@
 		log.Fatalf("godevHandler: %v", err)
 	}
 	mux.Handle("go.dev/", godev)
-	mux.Handle("learn.go.dev/", godev)
+
+	mux.Handle("blog.golang.org/", redirectPrefix("https://go.dev/blog/"))
+	mux.Handle("learn.go.dev/", redirectPrefix("https://go.dev/learn/"))
 
 	var h http.Handler = mux
 	if env.EnforceHosts() {
diff --git a/cmd/golangorg/server_test.go b/cmd/golangorg/server_test.go
index ec99405..0b6524e 100644
--- a/cmd/golangorg/server_test.go
+++ b/cmd/golangorg/server_test.go
@@ -16,10 +16,6 @@
 	"golang.org/x/website/internal/webtest"
 )
 
-func init() {
-	isTestBinary = true
-}
-
 func TestWeb(t *testing.T) {
 	h := NewHandler("../../_content", runtime.GOROOT())
 
@@ -34,6 +30,15 @@
 	}
 }
 
+var bad = []string{
+	"&amp;lt;",
+	"&amp;gt;",
+	"&amp;amp;",
+	" < ",
+	"<-",
+	"& ",
+}
+
 func TestAll(t *testing.T) {
 	h := NewHandler("../../_content", runtime.GOROOT())
 
@@ -53,6 +58,15 @@
 				h.ServeHTTP(rec, httptest.NewRequest("GET", url, nil))
 				if rec.Code != 200 && rec.Code != 301 {
 					t.Errorf("GET %s: %d, want 200\n%s", url, rec.Code, rec.Body.String())
+					return nil
+				}
+
+				s := rec.Body.String()
+				for _, b := range bad {
+					if strings.Contains(s, b) {
+						t.Errorf("GET %s: contains %s\n%s", url, b, s)
+						break
+					}
 				}
 			}
 			return nil
diff --git a/cmd/golangorg/testdata/blog.txt b/cmd/golangorg/testdata/blog.txt
new file mode 100644
index 0000000..4c7afc2
--- /dev/null
+++ b/cmd/golangorg/testdata/blog.txt
@@ -0,0 +1,53 @@
+GET https://go.dev/blog/
+body contains The Go Blog
+header Content-Type == text/html; charset=utf-8
+
+GET https://go.dev/blog/2010/08/defer-panic-and-recover.html
+redirect == /blog/defer-panic-and-recover
+
+GET https://go.dev/blog/upcoming-google-io-go-events
+redirect == /blog/io2010-preview
+
+GET https://go.dev/blog/strings
+body contains produces this mess
+body contains <div class="playground"
+body contains <pre contenteditable="true" spellcheck="false">package main
+
+GET https://go.dev/blog/race-detector
+body contains <span class="number">11&nbsp;&nbsp;</span>    start := time.Now()
+
+GET https://go.dev/blog/go2draft
+body contains <iframe
+
+GET https://go.dev/blog/gouk15
+body contains <img
+
+GET https://golang.org/blog/
+redirect == /blog
+
+GET https://golang.org/blog
+redirect == https://go.dev/blog
+
+GET https://go.dev/blog
+redirect == /blog/
+
+GET https://blog.golang.org/
+redirect == https://go.dev/blog/
+
+GET https://go.dev/blog/
+body contains The Go Blog
+
+GET https://blog.golang.org/x
+redirect == /x/
+
+GET https://blog.golang.org/x/
+redirect == https://go.dev/blog/x/
+
+GET https://go.dev/blog/x/
+code == 404
+
+GET https://blog.golang.org/go1.16
+redirect == https://go.dev/blog/go1.16
+
+GET https://go.dev/blog/go1.16
+body contains Go 1.16
diff --git a/blog/_content/10years.article b/go.dev/_content/blog/10years.md
similarity index 95%
rename from blog/_content/10years.article
rename to go.dev/_content/blog/10years.md
index 5c2d69a..7f7a1f7 100644
--- a/blog/_content/10years.article
+++ b/go.dev/_content/blog/10years.md
@@ -1,11 +1,11 @@
-# Go Turns 10
-8 Nov 2019
-Summary: Happy 10th birthday, Go!
+---
+title: Go Turns 10
+date: 2019-11-08
+by:
+- Russ Cox, for the Go team
+summary: Happy 10th birthday, Go!
+---
 
-Russ Cox, for the Go team
-rsc@golang.org
-
-##
 
 Happy birthday, Go!
 
@@ -21,7 +21,7 @@
 painted this delightful scene:
 
 <a href="10years/gopher10th-large.jpg">
-.image 10years/gopher10th-small.jpg _ 850
+{{image "10years/gopher10th-small.jpg" 850}}
 </a>
 
 Celebrating 10 years of Go makes me think back to early November 2009,
@@ -132,6 +132,6 @@
 <div>
 <center>
 <a href="10years/gopher10th-pin-large.jpg">
-.image 10years/gopher10th-pin-small.jpg _ 150
+{{image "10years/gopher10th-pin-small.jpg" 150}}
 </center>
 </div>
diff --git a/blog/_content/10years/gopher10th-large.jpg b/go.dev/_content/blog/10years/gopher10th-large.jpg
similarity index 100%
rename from blog/_content/10years/gopher10th-large.jpg
rename to go.dev/_content/blog/10years/gopher10th-large.jpg
Binary files differ
diff --git a/blog/_content/10years/gopher10th-pin-large.jpg b/go.dev/_content/blog/10years/gopher10th-pin-large.jpg
similarity index 100%
rename from blog/_content/10years/gopher10th-pin-large.jpg
rename to go.dev/_content/blog/10years/gopher10th-pin-large.jpg
Binary files differ
diff --git a/blog/_content/10years/gopher10th-pin-small.jpg b/go.dev/_content/blog/10years/gopher10th-pin-small.jpg
similarity index 100%
rename from blog/_content/10years/gopher10th-pin-small.jpg
rename to go.dev/_content/blog/10years/gopher10th-pin-small.jpg
Binary files differ
diff --git a/blog/_content/10years/gopher10th-small.jpg b/go.dev/_content/blog/10years/gopher10th-small.jpg
similarity index 100%
rename from blog/_content/10years/gopher10th-small.jpg
rename to go.dev/_content/blog/10years/gopher10th-small.jpg
Binary files differ
diff --git a/blog/_content/11years.article b/go.dev/_content/blog/11years.md
similarity index 97%
rename from blog/_content/11years.article
rename to go.dev/_content/blog/11years.md
index 1c2188f..41684b7 100644
--- a/blog/_content/11years.article
+++ b/go.dev/_content/blog/11years.md
@@ -1,10 +1,11 @@
-# Eleven Years of Go
-12:01 10 Nov 2020
-Summary: Happy Birthday, Go!
+---
+title: Eleven Years of Go
+date: 2020-11-10T12:01:00Z
+by:
+- Russ Cox, for the Go team
+summary: Happy Birthday, Go!
+---
 
-Russ Cox, for the Go team
-
-##
 
 Today we celebrate the eleventh birthday of the Go open source release.
 The parties we had for
diff --git a/blog/_content/11years/gophermask.jpg b/go.dev/_content/blog/11years/gophermask.jpg
similarity index 100%
rename from blog/_content/11years/gophermask.jpg
rename to go.dev/_content/blog/11years/gophermask.jpg
Binary files differ
diff --git a/blog/_content/1year.article b/go.dev/_content/blog/1year.md
similarity index 97%
rename from blog/_content/1year.article
rename to go.dev/_content/blog/1year.md
index cad82c6..f62379c 100644
--- a/blog/_content/1year.article
+++ b/go.dev/_content/blog/1year.md
@@ -1,12 +1,13 @@
-# Go: one year ago today
-10 Nov 2010
-Tags: birthday
-Summary: Happy 1st birthday, Go!
-OldURL: /go-one-year-ago-today
+---
+title: "Go: one year ago today"
+date: 2010-11-10
+by:
+- Andrew Gerrand
+tags:
+- birthday
+summary: Happy 1st birthday, Go!
+---
 
-Andrew Gerrand
-
-##
 
 On the 10th of November 2009 we launched the Go project:
 an open-source programming language with a focus on simplicity and efficiency.
diff --git a/blog/_content/2years.article b/go.dev/_content/blog/2years.md
similarity index 92%
rename from blog/_content/2years.article
rename to go.dev/_content/blog/2years.md
index 6dd1852..125ad90 100644
--- a/blog/_content/2years.article
+++ b/go.dev/_content/blog/2years.md
@@ -1,12 +1,15 @@
-# The Go Programming Language turns two
-10 Nov 2011
-Tags: appengine, community, gopher
-Summary: Happy 2nd birthday, Go!
-OldURL: /go-programming-language-turns-two
+---
+title: The Go Programming Language turns two
+date: 2011-11-10
+by:
+- Andrew Gerrand
+tags:
+- appengine
+- community
+- gopher
+summary: Happy 2nd birthday, Go!
+---
 
-Andrew Gerrand
-
-##
 
 Two years ago a small team at Google went public with their fledgling project -
 the Go Programming Language.
@@ -67,10 +70,10 @@
 I/O and other Go talks) and in vinyl form (received by every attendee at
 OSCON and now available at the [Google Store](http://www.googlestore.com/Fun/Go+Gopher+Figurine.axd)).
 
-.image 2years/2years-gophers.jpg
+{{image "2years/2years-gophers.jpg"}}
 
 And, most surprisingly, at Halloween he made an appearance with his gopher girlfriend!
 
-.image 2years/2years-costume.jpg
+{{image "2years/2years-costume.jpg"}}
 
 Photograph by [Chris Nokleberg](https://plus.google.com/106640494112897458359/posts).
diff --git a/blog/_content/2years/2years-costume.jpg b/go.dev/_content/blog/2years/2years-costume.jpg
similarity index 100%
rename from blog/_content/2years/2years-costume.jpg
rename to go.dev/_content/blog/2years/2years-costume.jpg
Binary files differ
diff --git a/blog/_content/2years/2years-gophers.jpg b/go.dev/_content/blog/2years/2years-gophers.jpg
similarity index 100%
rename from blog/_content/2years/2years-gophers.jpg
rename to go.dev/_content/blog/2years/2years-gophers.jpg
Binary files differ
diff --git a/blog/_content/3years.article b/go.dev/_content/blog/3years.md
similarity index 95%
rename from blog/_content/3years.article
rename to go.dev/_content/blog/3years.md
index 7ac1c78..c30a108 100644
--- a/blog/_content/3years.article
+++ b/go.dev/_content/blog/3years.md
@@ -1,12 +1,14 @@
-# Go turns three
-10 Nov 2012
-Tags: community, birthday
-Summary: Happy 3rd birthday, Go!
-OldURL: /go-turns-three
+---
+title: Go turns three
+date: 2012-11-10
+by:
+- Russ Cox
+tags:
+- community
+- birthday
+summary: Happy 3rd birthday, Go!
+---
 
-Russ Cox
-
-##
 
 The Go open source project is
 [three years old today](http://google-opensource.blogspot.com/2009/11/hey-ho-lets-go.html).
diff --git a/blog/_content/4years.article b/go.dev/_content/blog/4years.md
similarity index 96%
rename from blog/_content/4years.article
rename to go.dev/_content/blog/4years.md
index 711714d..97906ee 100644
--- a/blog/_content/4years.article
+++ b/go.dev/_content/blog/4years.md
@@ -1,15 +1,18 @@
-# Four years of Go
-10 Nov 2013
-Tags: community, birthday
-Summary: Happy 4th birthday, Go!
+---
+title: Four years of Go
+date: 2013-11-10
+by:
+- Andrew Gerrand
+tags:
+- community
+- birthday
+summary: Happy 4th birthday, Go!
+---
 
-Andrew Gerrand
-
-##
 
 Today marks the fourth anniversary of Go as an open source project.
 
-.image 4years/4years-gopher.png
+{{image "4years/4years-gopher.png"}}
 
 Rather than talk about our technical progress (there'll be much to talk about
 when we release Go 1.2 in a couple of weeks) we thought we would instead take
@@ -17,7 +20,7 @@
 
 Let's start with a chart:
 
-.image 4years/4years-graph.png
+{{image "4years/4years-graph.png"}}
 
 This chart shows the growth of Google searches for the term
 "[golang](http://www.google.com/trends/explore?hl=en-US#q=golang&date=10/2009+50m&cmpt=q)"
diff --git a/blog/_content/4years/4years-gopher.png b/go.dev/_content/blog/4years/4years-gopher.png
similarity index 100%
rename from blog/_content/4years/4years-gopher.png
rename to go.dev/_content/blog/4years/4years-gopher.png
Binary files differ
diff --git a/blog/_content/4years/4years-graph.png b/go.dev/_content/blog/4years/4years-graph.png
similarity index 100%
rename from blog/_content/4years/4years-graph.png
rename to go.dev/_content/blog/4years/4years-graph.png
Binary files differ
diff --git a/blog/_content/5years.article b/go.dev/_content/blog/5years.md
similarity index 95%
rename from blog/_content/5years.article
rename to go.dev/_content/blog/5years.md
index 0d513d3..732553c 100644
--- a/blog/_content/5years.article
+++ b/go.dev/_content/blog/5years.md
@@ -1,11 +1,11 @@
-# Half a decade with Go
-10 Nov 2014
-Summary: Happy 5th birthday, Go!
+---
+title: Half a decade with Go
+date: 2014-11-10
+by:
+- Andrew Gerrand
+summary: Happy 5th birthday, Go!
+---
 
-Andrew Gerrand
-adg@golang.org
-
-##
 
 Five years ago we launched the Go project. It seems like only yesterday that we
 were preparing the initial public release: our
@@ -22,7 +22,7 @@
 tailored to their needs as working software engineers. These few would form the
 kernel of the Go community.
 
-.image 5years/gophers5th.jpg _ 850
+{{image "5years/gophers5th.jpg" 850}}
 
 [_Gopher_](/gopher) _illustration by_ [_Renee French_](http://reneefrench.blogspot.com.au/)
 
@@ -56,7 +56,7 @@
 Go projects. For the Go team, it is very satisfying to meet so many programmers
 that share our vision and excitement.
 
-.image 5years/conferences.jpg
+{{image "5years/conferences.jpg"}}
 
 _More than 1,200 gophers attended GopherCon in Denver and dotGo in Paris._
 
diff --git a/blog/_content/5years/conferences.jpg b/go.dev/_content/blog/5years/conferences.jpg
similarity index 100%
rename from blog/_content/5years/conferences.jpg
rename to go.dev/_content/blog/5years/conferences.jpg
Binary files differ
diff --git a/blog/_content/5years/gophers5th.jpg b/go.dev/_content/blog/5years/gophers5th.jpg
similarity index 100%
rename from blog/_content/5years/gophers5th.jpg
rename to go.dev/_content/blog/5years/gophers5th.jpg
Binary files differ
diff --git a/blog/_content/6years.article b/go.dev/_content/blog/6years.md
similarity index 93%
rename from blog/_content/6years.article
rename to go.dev/_content/blog/6years.md
index fa70b8e..ad13245 100644
--- a/blog/_content/6years.article
+++ b/go.dev/_content/blog/6years.md
@@ -1,11 +1,11 @@
-# Six years of Go
-10 Nov 2015
-Summary: Happy 6th birthday, Go!
+---
+title: Six years of Go
+date: 2015-11-10
+by:
+- Andrew Gerrand
+summary: Happy 6th birthday, Go!
+---
 
-Andrew Gerrand
-adg@golang.org
-
-##
 
 Six years ago today the Go language was released as an open source project.
 Since then, more than 780 contributors have made over 30,000 commits to the
@@ -15,7 +15,7 @@
 [the](https://blog.golang.org/gouk15)
 [world](https://blog.golang.org/gopherchina) with regularity.
 
-.image 6years/6years-gopher.png
+{{image "6years/6years-gopher.png"}}
 
 In August we [released Go 1.5](https://blog.golang.org/go1.5), the most
 significant release since Go 1. It features a completely
diff --git a/blog/_content/6years/6years-gopher.png b/go.dev/_content/blog/6years/6years-gopher.png
similarity index 100%
rename from blog/_content/6years/6years-gopher.png
rename to go.dev/_content/blog/6years/6years-gopher.png
Binary files differ
diff --git a/blog/_content/7years.article b/go.dev/_content/blog/7years.md
similarity index 95%
rename from blog/_content/7years.article
rename to go.dev/_content/blog/7years.md
index 2a1dae2..921fcb5 100644
--- a/blog/_content/7years.article
+++ b/go.dev/_content/blog/7years.md
@@ -1,11 +1,11 @@
-# Seven years of Go
-10 Nov 2016
-Summary: Happy 7th birthday, Go!
+---
+title: Seven years of Go
+date: 2016-11-10
+by:
+- The Go Team
+summary: Happy 7th birthday, Go!
+---
 
-The Go Team
-rsc@golang.org
-
-##
 
 <img src="7years/gopherbelly300.jpg" align="right">
 
diff --git a/blog/_content/7years/gopherbelly300.jpg b/go.dev/_content/blog/7years/gopherbelly300.jpg
similarity index 100%
rename from blog/_content/7years/gopherbelly300.jpg
rename to go.dev/_content/blog/7years/gopherbelly300.jpg
Binary files differ
diff --git a/blog/_content/8years.article b/go.dev/_content/blog/8years.md
similarity index 95%
rename from blog/_content/8years.article
rename to go.dev/_content/blog/8years.md
index 4a9d39c..ceba2f3 100644
--- a/blog/_content/8years.article
+++ b/go.dev/_content/blog/8years.md
@@ -1,11 +1,14 @@
-# Eight years of Go
-10 Nov 2017
-Tags: community, birthday
-Summary: Happy 8th birthday, Go!
+---
+title: Eight years of Go
+date: 2017-11-10
+by:
+- Steve Francia
+tags:
+- community
+- birthday
+summary: Happy 8th birthday, Go!
+---
 
-Steve Francia
-
-##
 
 Today we celebrate 8 years since Go was released as an open source project.
 During [Go’s 4th anniversary](https://blog.golang.org/4years), Andrew
@@ -17,7 +20,7 @@
 popularity, what was 100 four years ago is now a mere 17. Go’s popularity has
 increased exponentially over the last 8 years and continues to grow.
 
-.image 8years/image1.png
+{{image "8years/image1.png"}}
 
 Source: [trends.google.com](https://trends.google.com/trends/explore?date=2009-10-01%202017-10-30&q=golang&hl=en-US)
 
@@ -30,7 +33,7 @@
 **52% growth over the previous year**. In growth, Go swapped places with
 Javascript, which fell to the second spot with 44%.
 
-.image 8years/image2.png
+{{image "8years/image2.png"}}
 
 Source: [octoverse.github.com](https://octoverse.github.com/)
 
@@ -38,8 +41,8 @@
 , Go was the only language that was both on the **top 5 most loved and top 5 most wanted** languages.
 People who use Go, love it, and the people who aren’t using Go, want to be.
 
-.image 8years/image3.png
-.image 8years/image4.png
+{{image "8years/image3.png"}}
+{{image "8years/image4.png"}}
 
 Source: [insights.stackoverflow.com/survey/2017](https://insights.stackoverflow.com/survey/2017#most-loved-dreaded-and-wanted)
 
@@ -77,7 +80,7 @@
 first [Go contributor workshop](https://blog.golang.org/contributor-workshop)
 where hundreds of people came to make their first Go contribution.
 
-.image 8years/photo.jpg
+{{image "8years/photo.jpg"}}
 
 Photo by Sameer Ajmani
 
diff --git a/blog/_content/8years/image1.png b/go.dev/_content/blog/8years/image1.png
similarity index 100%
rename from blog/_content/8years/image1.png
rename to go.dev/_content/blog/8years/image1.png
Binary files differ
diff --git a/blog/_content/8years/image2.png b/go.dev/_content/blog/8years/image2.png
similarity index 100%
rename from blog/_content/8years/image2.png
rename to go.dev/_content/blog/8years/image2.png
Binary files differ
diff --git a/blog/_content/8years/image3.png b/go.dev/_content/blog/8years/image3.png
similarity index 100%
rename from blog/_content/8years/image3.png
rename to go.dev/_content/blog/8years/image3.png
Binary files differ
diff --git a/blog/_content/8years/image4.png b/go.dev/_content/blog/8years/image4.png
similarity index 100%
rename from blog/_content/8years/image4.png
rename to go.dev/_content/blog/8years/image4.png
Binary files differ
diff --git a/blog/_content/8years/photo.jpg b/go.dev/_content/blog/8years/photo.jpg
similarity index 100%
rename from blog/_content/8years/photo.jpg
rename to go.dev/_content/blog/8years/photo.jpg
Binary files differ
diff --git a/blog/_content/9years.article b/go.dev/_content/blog/9years.md
similarity index 94%
rename from blog/_content/9years.article
rename to go.dev/_content/blog/9years.md
index 71b3137..ee57977 100644
--- a/blog/_content/9years.article
+++ b/go.dev/_content/blog/9years.md
@@ -1,9 +1,13 @@
-# Nine years of Go
-10 Nov 2018
-Tags: community, birthday
-Summary: Happy 9th birthday, Go!
-
-Steve Francia
+---
+title: Nine years of Go
+date: 2018-11-10
+by:
+- Steve Francia
+tags:
+- community
+- birthday
+summary: Happy 9th birthday, Go!
+---
 
 ## Introduction
 
@@ -57,7 +61,7 @@
 The Go community is truly global.
 At GopherCon Europe in Iceland this past summer, gophers literally spanned the gap between the continents.
 
-.image 9years/9years-iceland.jpg _ 800
+{{image "9years/9years-iceland.jpg" 800}}
 
 _(Photo by Winter Francia.)_
 
@@ -85,7 +89,7 @@
 The project hit a major milestone in mid-2018 when, for the first time,
 we had more contributions coming from the community than the Go team.
 
-.image 9years/9years-graph.png _ 600
+{{image "9years/9years-graph.png" 600}}
 
 ## Thank You
 
diff --git a/blog/_content/9years/9years-graph.png b/go.dev/_content/blog/9years/9years-graph.png
similarity index 100%
rename from blog/_content/9years/9years-graph.png
rename to go.dev/_content/blog/9years/9years-graph.png
Binary files differ
diff --git a/blog/_content/9years/9years-iceland.jpg b/go.dev/_content/blog/9years/9years-iceland.jpg
similarity index 100%
rename from blog/_content/9years/9years-iceland.jpg
rename to go.dev/_content/blog/9years/9years-iceland.jpg
Binary files differ
diff --git a/blog/_content/README b/go.dev/_content/blog/README.md
similarity index 100%
rename from blog/_content/README
rename to go.dev/_content/blog/README.md
diff --git a/go.dev/_content/blog/a-conversation-with-the-go-team.md b/go.dev/_content/blog/a-conversation-with-the-go-team.md
new file mode 100644
index 0000000..bb939de
--- /dev/null
+++ b/go.dev/_content/blog/a-conversation-with-the-go-team.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/io2013-chat
+---
diff --git a/go.dev/_content/blog/a-new-go-api-for-protocol-buffers.md b/go.dev/_content/blog/a-new-go-api-for-protocol-buffers.md
new file mode 100644
index 0000000..6871e52
--- /dev/null
+++ b/go.dev/_content/blog/a-new-go-api-for-protocol-buffers.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/protobuf-apiv2
+---
diff --git a/go.dev/_content/blog/advanced-go-concurrency-patterns.md b/go.dev/_content/blog/advanced-go-concurrency-patterns.md
new file mode 100644
index 0000000..fa2f4c9
--- /dev/null
+++ b/go.dev/_content/blog/advanced-go-concurrency-patterns.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/io2013-talk-concurrency
+---
diff --git a/go.dev/_content/blog/all.md b/go.dev/_content/blog/all.md
new file mode 100644
index 0000000..b316404
--- /dev/null
+++ b/go.dev/_content/blog/all.md
@@ -0,0 +1,20 @@
+---
+title: Blog Index
+---
+
+<div id="blogindex">
+
+{{range newest (pages "/blog/*.md") -}}
+{{if .date}}
+<p class="blogtitle">
+  <a href="{{.URL}}">{{.title}}</a>, <span class="date">{{.date.Format "2 January 2006"}}</span><br>
+  <span class="author">{{with .by}}{{by .}}<br>{{end}}</span>
+  {{with .Tags}}<span class="tags">{{range .}}{{.}} {{end}}</span>{{end}}
+</p>
+<p class="blogsummary">
+  {{.summary}}
+</p>
+{{end}}
+{{end}}
+
+</div>
diff --git a/blog/_content/appengine-155.article b/go.dev/_content/blog/appengine-155.md
similarity index 88%
rename from blog/_content/appengine-155.article
rename to go.dev/_content/blog/appengine-155.md
index 37cf290..5d14934 100644
--- a/blog/_content/appengine-155.article
+++ b/go.dev/_content/blog/appengine-155.md
@@ -1,12 +1,15 @@
-# Go App Engine SDK 1.5.5 released
-11 Oct 2011
-Tags: appengine, gofix, release
-Summary: Go App Engine SDK 1.5.5 includes Go release.r60.2.
-OldURL: /go-app-engine-sdk-155-released
+---
+title: Go App Engine SDK 1.5.5 released
+date: 2011-10-11
+by:
+- Andrew Gerrand
+tags:
+- appengine
+- gofix
+- release
+summary: Go App Engine SDK 1.5.5 includes Go release.r60.2.
+---
 
-Andrew Gerrand
-
-##
 
 Today we released version 1.5.5 the Go App Engine SDK.
 You can download it from the [App Engine downloads page](http://code.google.com/appengine/downloads.html).
diff --git a/blog/_content/appengine-171.article b/go.dev/_content/blog/appengine-171.md
similarity index 91%
rename from blog/_content/appengine-171.article
rename to go.dev/_content/blog/appengine-171.md
index 57c047d..529feab 100644
--- a/blog/_content/appengine-171.article
+++ b/go.dev/_content/blog/appengine-171.md
@@ -1,12 +1,14 @@
-# Go updates in App Engine 1.7.1
-22 Aug 2012
-Tags: appengine, release
-Summary: App Engine SDK 1.7.1 adds memcache and other functionality for Go.
-OldURL: /go-updates-in-app-engine-171
+---
+title: Go updates in App Engine 1.7.1
+date: 2012-08-22
+by:
+- Andrew Gerrand
+tags:
+- appengine
+- release
+summary: App Engine SDK 1.7.1 adds memcache and other functionality for Go.
+---
 
-Andrew Gerrand
-
-##
 
 This week we released version 1.7.1 of the App Engine SDK.
 It includes some significant updates specific to the App Engine runtime for Go.
diff --git a/blog/_content/appengine-dec2013.article b/go.dev/_content/blog/appengine-dec2013.md
similarity index 94%
rename from blog/_content/appengine-dec2013.article
rename to go.dev/_content/blog/appengine-dec2013.md
index 030323f..a0d2cca 100644
--- a/blog/_content/appengine-dec2013.article
+++ b/go.dev/_content/blog/appengine-dec2013.md
@@ -1,11 +1,13 @@
-# Go on App Engine: tools, tests, and concurrency
-13 Dec 2013
-Tags: appengine
-Summary: Announcing improvements to Go on App Engine.
-
-Andrew Gerrand
-
-Johan Euphrosine
+---
+title: "Go on App Engine: tools, tests, and concurrency"
+date: 2013-12-13
+by:
+- Andrew Gerrand
+- Johan Euphrosine
+tags:
+- appengine
+summary: Announcing improvements to Go on App Engine.
+---
 
 ## Background
 
diff --git a/blog/_content/appengine-ga.article b/go.dev/_content/blog/appengine-ga.md
similarity index 89%
rename from blog/_content/appengine-ga.article
rename to go.dev/_content/blog/appengine-ga.md
index 964efc1..96f25b6 100644
--- a/blog/_content/appengine-ga.article
+++ b/go.dev/_content/blog/appengine-ga.md
@@ -1,12 +1,14 @@
-# Go for App Engine is now generally available
-21 Jul 2011
-Tags: appengine, release
-Summary: You can use Go on App Engine now!
-OldURL: /go-for-app-engine-is-now-generally
+---
+title: Go for App Engine is now generally available
+date: 2011-07-21
+by:
+- Andrew Gerrand
+tags:
+- appengine
+- release
+summary: You can use Go on App Engine now!
+---
 
-Andrew Gerrand
-
-##
 
 The Go and App Engine teams are excited to announce that the Go runtime
 for App Engine is now generally available.
diff --git a/blog/_content/appengine-go111.article b/go.dev/_content/blog/appengine-go111.md
similarity index 92%
rename from blog/_content/appengine-go111.article
rename to go.dev/_content/blog/appengine-go111.md
index 7d0dd8a..adb2ed7 100644
--- a/blog/_content/appengine-go111.article
+++ b/go.dev/_content/blog/appengine-go111.md
@@ -1,13 +1,14 @@
-# Announcing App Engine’s New Go 1.11 Runtime
-16 Oct 2018
-Tags: appengine
-Summary: Google Cloud is announcing a new Go 1.11 runtime for App Engine, with fewer limits on app structure.
+---
+title: Announcing App Engine’s New Go 1.11 Runtime
+date: 2018-10-16
+by:
+- Eno Compton
+- Tyler Bui-Palsulich
+tags:
+- appengine
+summary: Google Cloud is announcing a new Go 1.11 runtime for App Engine, with fewer limits on app structure.
+---
 
-Eno Compton
-
-Tyler Bui-Palsulich
-
-##
 
 [App Engine](https://cloud.google.com/appengine/) launched
 [experimental support for Go](https://blog.golang.org/go-and-google-app-engine)
@@ -41,7 +42,7 @@
 
 First, you create the application in your `GOPATH`:
 
-.code appengine/main.go
+{{code "appengine/main.go"}}
 
 The code contains an idiomatic setup for a small HTTP server that responds with
 “Hello, 世界.” If you have previous App Engine experience, you’ll notice the
diff --git a/blog/_content/appengine-gopath.article b/go.dev/_content/blog/appengine-gopath.md
similarity index 95%
rename from blog/_content/appengine-gopath.article
rename to go.dev/_content/blog/appengine-gopath.md
index d9f995b..2160d27 100644
--- a/blog/_content/appengine-gopath.article
+++ b/go.dev/_content/blog/appengine-gopath.md
@@ -1,10 +1,14 @@
-# The App Engine SDK and workspaces (GOPATH)
-9 Jan 2013
-Tags: appengine, tools, gopath
-Summary: App Engine SDK 1.7.4 adds support for GOPATH-style workspaces.
-OldURL: /the-app-engine-sdk-and-workspaces-gopath
-
-Andrew Gerrand
+---
+title: The App Engine SDK and workspaces (GOPATH)
+date: 2013-01-09
+by:
+- Andrew Gerrand
+tags:
+- appengine
+- tools
+- gopath
+summary: App Engine SDK 1.7.4 adds support for GOPATH-style workspaces.
+---
 
 ## Introduction
 
diff --git a/blog/_content/appengine-scalable.article b/go.dev/_content/blog/appengine-scalable.md
similarity index 88%
rename from blog/_content/appengine-scalable.article
rename to go.dev/_content/blog/appengine-scalable.md
index 4a91040..2172501 100644
--- a/blog/_content/appengine-scalable.article
+++ b/go.dev/_content/blog/appengine-scalable.md
@@ -1,12 +1,14 @@
-# Writing scalable App Engine applications
-1 Nov 2011
-Tags: appengine, optimization
-Summary: How to build scalable web applications using Go with Google App Engine.
-OldURL: /writing-scalable-app-engine
+---
+title: Writing scalable App Engine applications
+date: 2011-11-01
+by:
+- David Symonds
+tags:
+- appengine
+- optimization
+summary: How to build scalable web applications using Go with Google App Engine.
+---
 
-David Symonds
-
-##
 
 Back in May, we [announced](https://blog.golang.org/2011/05/go-and-google-app-engine.html)
 the Go runtime for App Engine.
diff --git a/blog/_content/appengine.article b/go.dev/_content/blog/appengine.md
similarity index 93%
rename from blog/_content/appengine.article
rename to go.dev/_content/blog/appengine.md
index 89b8244..dac584b 100644
--- a/blog/_content/appengine.article
+++ b/go.dev/_content/blog/appengine.md
@@ -1,16 +1,16 @@
-# Go and Google App Engine
-10 May 2011
-Tags: appengine, release
-Summary: Announcing support for Go in Google App Engine.
-OldURL: /go-and-google-app-engine
+---
+title: Go and Google App Engine
+date: 2011-05-10
+by:
+- David Symonds
+- Nigel Tao
+- Andrew Gerrand
+tags:
+- appengine
+- release
+summary: Announcing support for Go in Google App Engine.
+---
 
-David Symonds
-
-Nigel Tao
-
-Andrew Gerrand
-
-##
 
 Google’s App Engine provides a reliable,
 scalable, easy way to build and deploy applications for the web.
diff --git a/blog/_content/appengine/main.go b/go.dev/_content/blog/appengine/main.go
similarity index 100%
rename from blog/_content/appengine/main.go
rename to go.dev/_content/blog/appengine/main.go
diff --git a/blog/_content/bossie.article b/go.dev/_content/blog/bossie.md
similarity index 86%
rename from blog/_content/bossie.article
rename to go.dev/_content/blog/bossie.md
index bff5a23..3a3d626 100644
--- a/blog/_content/bossie.article
+++ b/go.dev/_content/blog/bossie.md
@@ -1,11 +1,11 @@
-# Go Wins 2010 Bossie Award
-6 Sep 2010
-Summary: Go wins a 2010 Bossie Award for “best open source application development software.” 
-OldURL: /go-wins-2010-bossie-award
+---
+title: Go Wins 2010 Bossie Award
+date: 2010-09-06
+by:
+- Andrew Gerrand
+summary: Go wins a 2010 Bossie Award for “best open source application development software.”
+---
 
-Andrew Gerrand
-
-##
 
 The Go project has been awarded a [Bossie Award](http://www.infoworld.com/d/open-source/bossie-awards-2010-the-best-open-source-application-development-software-140&current=2&last=1)
 for "best open source application development software." The [Bossie Awards](http://www.infoworld.com/d/open-source/bossie-awards-2010-the-best-open-source-software-the-year-115)
diff --git a/go.dev/_content/blog/building-stathat-with-go.md b/go.dev/_content/blog/building-stathat-with-go.md
new file mode 100644
index 0000000..1af6cbe
--- /dev/null
+++ b/go.dev/_content/blog/building-stathat-with-go.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/stathat
+---
diff --git a/go.dev/_content/blog/c-go-cgo.md b/go.dev/_content/blog/c-go-cgo.md
new file mode 100644
index 0000000..8cb5f2c
--- /dev/null
+++ b/go.dev/_content/blog/c-go-cgo.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/cgo
+---
diff --git a/blog/_content/cgo.article b/go.dev/_content/blog/cgo.md
similarity index 96%
rename from blog/_content/cgo.article
rename to go.dev/_content/blog/cgo.md
index 66988fa..013b45a 100644
--- a/blog/_content/cgo.article
+++ b/go.dev/_content/blog/cgo.md
@@ -1,10 +1,13 @@
-# C? Go? Cgo!
-17 Mar 2011
-Tags: cgo, technical
-Summary: How to use cgo to let Go packages call C code.
-OldURL: /c-go-cgo
-
-Andrew Gerrand
+---
+title: C? Go? Cgo!
+date: 2011-03-17
+by:
+- Andrew Gerrand
+tags:
+- cgo
+- technical
+summary: How to use cgo to let Go packages call C code.
+---
 
 ## Introduction
 
diff --git a/blog/_content/codelab-share.article b/go.dev/_content/blog/codelab-share.md
similarity index 93%
rename from blog/_content/codelab-share.article
rename to go.dev/_content/blog/codelab-share.md
index 03fbab6..9e5a84a 100644
--- a/blog/_content/codelab-share.article
+++ b/go.dev/_content/blog/codelab-share.md
@@ -1,12 +1,14 @@
-# Share Memory By Communicating
-13 Jul 2010
-Tags: concurrency, technical
-Summary: A preview of the new Go codelab, Share Memory by Communicating.
-OldURL: /share-memory-by-communicating
+---
+title: Share Memory By Communicating
+date: 2010-07-13
+by:
+- Andrew Gerrand
+tags:
+- concurrency
+- technical
+summary: A preview of the new Go codelab, Share Memory by Communicating.
+---
 
-Andrew Gerrand
-
-##
 
 Traditional threading models (commonly used when writing Java,
 C++, and Python programs, for example) require the programmer to communicate
@@ -44,6 +46,7 @@
 
 And then a Poller function (many of which would run in separate threads) might look something like this:
 
+{{raw `
 	func Poller(res *Resources) {
 	    for {
 	        // get the least recently-polled Resource
@@ -75,6 +78,7 @@
 	        res.lock.Unlock()
 	    }
 	}
+`}}
 
 This function is about a page long, and requires more detail to make it complete.
 It doesn't even include the URL polling logic (which,
@@ -86,6 +90,7 @@
 from an input channel,
 and sends them to an output channel when they're done.
 
+{{raw `
 	type Resource string
 
 	func Poller(in, out chan *Resource) {
@@ -96,6 +101,7 @@
 	        out <- r
 	    }
 	}
+`}}
 
 The delicate logic from the previous example is conspicuously absent,
 and our Resource data structure no longer contains bookkeeping data.
diff --git a/go.dev/_content/blog/community-outreach-working-group.md b/go.dev/_content/blog/community-outreach-working-group.md
new file mode 100644
index 0000000..e5d3a0d
--- /dev/null
+++ b/go.dev/_content/blog/community-outreach-working-group.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/cwg
+---
diff --git a/go.dev/_content/blog/company-questionnaire2018.md b/go.dev/_content/blog/company-questionnaire2018.md
new file mode 100644
index 0000000..c8e7b67
--- /dev/null
+++ b/go.dev/_content/blog/company-questionnaire2018.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/survey2018-company
+---
diff --git a/go.dev/_content/blog/concurrency-is-not-parallelism.md b/go.dev/_content/blog/concurrency-is-not-parallelism.md
new file mode 100644
index 0000000..ef4213c
--- /dev/null
+++ b/go.dev/_content/blog/concurrency-is-not-parallelism.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/waza-talk
+---
diff --git a/blog/_content/concurrency-timeouts.article b/go.dev/_content/blog/concurrency-timeouts.md
similarity index 92%
rename from blog/_content/concurrency-timeouts.article
rename to go.dev/_content/blog/concurrency-timeouts.md
index 8237e7d..c903416 100644
--- a/blog/_content/concurrency-timeouts.article
+++ b/go.dev/_content/blog/concurrency-timeouts.md
@@ -1,12 +1,14 @@
-# Go Concurrency Patterns: Timing out, moving on
-23 Sep 2010
-Tags: concurrency, technical
-Summary: How to implement timeouts using Go's concurrency support.
-OldURL: /go-concurrency-patterns-timing-out-and
+---
+title: "Go Concurrency Patterns: Timing out, moving on"
+date: 2010-09-23
+by:
+- Andrew Gerrand
+tags:
+- concurrency
+- technical
+summary: How to implement timeouts using Go's concurrency support.
+---
 
-Andrew Gerrand
-
-##
 
 Concurrent programming has its own idioms.
 A good example is timeouts. Although Go's channels do not support them directly,
@@ -16,22 +18,26 @@
 We would start by creating a signalling channel and launching a goroutine
 that sleeps before sending on the channel:
 
+{{raw `
 	timeout := make(chan bool, 1)
 	go func() {
 	    time.Sleep(1 * time.Second)
 	    timeout <- true
 	}()
+`}}
 
 We can then use a `select` statement to receive from either `ch` or `timeout`.
 If nothing arrives on `ch` after one second,
 the timeout case is selected and the attempt to read from ch is abandoned.
 
+{{raw `
 	select {
 	case <-ch:
 	    // a read from ch has occurred
 	case <-timeout:
 	    // the read from ch has timed out
 	}
+`}}
 
 The `timeout` channel is buffered with space for 1 value,
 allowing the timeout goroutine to send to the channel and then exit.
@@ -52,6 +58,7 @@
 The function `Query` takes a slice of database connections and a `query` string.
 It queries each of the databases in parallel and returns the first response it receives:
 
+{{raw `
 	func Query(conns []Conn, query string) Result {
 	    ch := make(chan Result)
 	    for _, conn := range conns {
@@ -64,6 +71,7 @@
 	    }
 	    return <-ch
 	}
+`}}
 
 In this example, the closure does a non-blocking send,
 which it achieves by using the send operation in `select` statement with a `default` case.
diff --git a/blog/_content/conduct-2018.article b/go.dev/_content/blog/conduct-2018.md
similarity index 95%
rename from blog/_content/conduct-2018.article
rename to go.dev/_content/blog/conduct-2018.md
index 2fb5ffa..f4e8a07 100644
--- a/blog/_content/conduct-2018.article
+++ b/go.dev/_content/blog/conduct-2018.md
@@ -1,11 +1,13 @@
-# Updating the Go Code of Conduct
-23 May 2018
-Tags: conduct
-Summary: Revising the Go Code of Conduct.
+---
+title: Updating the Go Code of Conduct
+date: 2018-05-23
+by:
+- Steve Francia
+tags:
+- conduct
+summary: Revising the Go Code of Conduct.
+---
 
-Steve Francia
-
-##
 
 In November 2015, we introduced the Go Code of Conduct.
 It was developed in a collaboration between
diff --git a/blog/_content/constants.article b/go.dev/_content/blog/constants.md
similarity index 91%
rename from blog/_content/constants.article
rename to go.dev/_content/blog/constants.md
index 63ecbf4..e7017fd 100644
--- a/blog/_content/constants.article
+++ b/go.dev/_content/blog/constants.md
@@ -1,15 +1,18 @@
-# Constants
-25 Aug 2014
-Tags: constants
-Summary: An introduction to constants in Go.
-
-Rob Pike
+---
+title: Constants
+date: 2014-08-25
+by:
+- Rob Pike
+tags:
+- constants
+summary: An introduction to constants in Go.
+---
 
 ## Introduction
 
 Go is a statically typed language that does not permit operations that mix numeric types.
 You can't add a `float64` to an `int`, or even an `int32` to an `int`.
-Yet it is legal to write `1e6*time.Second` or `math.Exp(1)` or even `1<<('\t'+2.0)`.
+Yet it is legal to write `1e6*time.Second` or `math.Exp(1)` or even {{raw "`1<<('\t'+2.0)`"}}.
 In Go, constants, unlike variables, behave pretty much like regular numbers.
 This post explains why that is and what it means.
 
@@ -126,20 +129,20 @@
 This means that `typedHello` has Go type `string`, and cannot be assigned to a Go variable of a different type.
 That is to say, this code works:
 
-.play -edit constants/string1.go /START/,/STOP/
+{{play "constants/string1.go" `/START/` `/STOP/`}}
 
 but this does not:
 
-.play -edit constants/string2.go /START/,/STOP/
+{{play "constants/string2.go" `/START/` `/STOP/`}}
 
 The variable `m` has type `MyString` and cannot be assigned a value of a different type.
 It can only be assigned values of type `MyString`, like this:
 
-.play -edit constants/string3.go /START/,/STOP/
+{{play "constants/string3.go" `/START/` `/STOP/`}}
 
 or by forcing the issue with a conversion, like this:
 
-.play -edit constants/string4.go /START/,/STOP/
+{{play "constants/string4.go" `/START/` `/STOP/`}}
 
 Returning to our _untyped_ string constant,
 it has the helpful property that, since it has no type,
@@ -194,7 +197,7 @@
 Sometimes when we use a constant, however, the destination of the value is not so clear.
 For instance consider this statement:
 
-.play -edit constants/default1.go /START/,/STOP/
+{{play "constants/default1.go" `/START/` `/STOP/`}}
 
 The signature of `fmt.Printf` is
 
@@ -208,11 +211,11 @@
 You can see the result in this example, which uses the format `%v` to print
 the value and `%T` to print the type of the value being passed to `fmt.Printf`:
 
-.play -edit constants/default2.go /START/,/STOP/
+{{play "constants/default2.go" `/START/` `/STOP/`}}
 
 If the constant has a type, that goes into the interface, as this example shows:
 
-.play -edit constants/default3.go /START/,/STOP/
+{{play "constants/default3.go" `/START/` `/STOP/`}}
 
 (For more information about how interface values work,
 see the first sections of [this blog post](https://blog.golang.org/laws-of-reflection).)
@@ -232,7 +235,7 @@
 and imaginary constants to `complex128`.
 Here's our canonical print statement used repeatedly to show the default types in action:
 
-.play -edit constants/syntax.go /START/,/STOP/
+{{play "constants/syntax.go" `/START/` `/STOP/`}}
 
 (Exercise: Explain the result for `'x'`.)
 
@@ -242,7 +245,7 @@
 The values `true` and `false` are untyped boolean constants that can be assigned to any boolean variable,
 but once given a type, boolean variables cannot be mixed:
 
-.play -edit constants/bool.go /START/,/STOP/
+{{play "constants/bool.go" `/START/` `/STOP/`}}
 
 Run the example and see what happens, then comment out the "Bad" line and run it again.
 The pattern here follows exactly that of string constants.
@@ -252,13 +255,13 @@
 Floating-point constants are just like boolean constants in most respects.
 Our standard example works as expected in translation:
 
-.play -edit constants/float1.go /START/,/STOP/
+{{play "constants/float1.go" `/START/` `/STOP/`}}
 
 One wrinkle is that there are _two_ floating-point types in Go: `float32` and `float64`.
 The default type for a floating-point constant is `float64`, although an untyped floating-point
 constant can be assigned to a `float32` value just fine:
 
-.play -edit constants/float2.go /START/,/STOP/
+{{play "constants/float2.go" `/START/` `/STOP/`}}
 
 Floating-point values are a good place to introduce the concept of overflow, or the range of values.
 
@@ -266,11 +269,11 @@
 But when they are assigned to a variable the value must be able to fit in the destination.
 We can declare a constant with a very large value:
 
-.code constants/float3.go /Huge/
+{{code "constants/float3.go" `/Huge/`}}
 
 —that's just a number, after all—but we can't assign it or even print it. This statement won't even compile:
 
-.play -edit constants/float3.go /Println/
+{{play "constants/float3.go" `/Println/`}}
 
 The error is, "constant 1.00000e+1000 overflows float64", which is true.
 But `Huge` might be useful: we can use it in expressions with other constants
@@ -278,7 +281,7 @@
 can be represented in the range of a `float64`.
 The statement,
 
-.play -edit constants/float4.go /Println/
+{{play "constants/float4.go" `/Println/`}}
 
 prints `10`, as one would expect.
 
@@ -294,7 +297,7 @@
 the assignment will create the `float64` (or `float32`)
 value closest to the high-precision value. This snippet
 
-.play -edit constants/float5.go /START/,/STOP/
+{{play "constants/float5.go" `/START/` `/STOP/`}}
 
 prints `3.141592653589793`.
 
@@ -311,7 +314,7 @@
 Complex constants behave a lot like floating-point constants.
 Here's a version of our now-familiar litany translated into complex numbers:
 
-.play -edit constants/complex1.go /START/,/STOP/
+{{play "constants/complex1.go" `/START/` `/STOP/`}}
 
 The default type of a complex number is `complex128`, the larger-precision version composed of two `float64` values.
 
@@ -324,20 +327,20 @@
 What if that number is a complex number with no imaginary part, that is, a real?
 Here's one:
 
-.code constants/complex2.go /const Two/
+{{code "constants/complex2.go" `/const Two/`}}
 
 That's an untyped complex constant.
 Even though it has no imaginary part, the _syntax_ of the expression defines it to have default type `complex128`.
 Therefore, if we use it to declare a variable, the default type will be `complex128`. The snippet
 
-.play -edit constants/complex2.go /START/,/STOP/
+{{play "constants/complex2.go" `/START/` `/STOP/`}}
 
 prints `complex128:` `(2+0i)`.
 But numerically, `Two` can be stored in a scalar floating-point number,
 a `float64` or `float32`, with no loss of information.
 Thus we can assign `Two` to a `float64`, either in an initialization or an assignment, without problems:
 
-.play -edit constants/complex3.go /START/,/STOP/
+{{play "constants/complex3.go" `/START/` `/STOP/`}}
 
 The output is `2` `and` `2`.
 Even though `Two` is a complex constant, it can be assigned to scalar floating-point variables.
@@ -350,7 +353,7 @@
 they play by the same rules.
 For the last time, here is our familiar example, using just `int` this time:
 
-.play -edit constants/int1.go /START/,/STOP/
+{{play "constants/int1.go" `/START/` `/STOP/`}}
 
 The same example could be built for any of the integer types, which are:
 
@@ -385,16 +388,16 @@
 For instance, `int8` has range -128 through 127,
 so constants outside of that range can never be assigned to a variable of type `int8`:
 
-.play -edit constants/int2.go /var/
+{{play "constants/int2.go" `/var/`}}
 
 Similarly, `uint8`, also known as `byte`,
 has range 0 through 255, so a large or negative constant cannot be assigned to a `uint8`:
 
-.play -edit constants/int3.go /var/
+{{play "constants/int3.go" `/var/`}}
 
 This type-checking can catch mistakes like this one:
 
-.play -edit constants/int4.go /START/,/STOP/
+{{play "constants/int4.go" `/START/` `/STOP/`}}
 
 If the compiler complains about your use of a constant, it's likely a real bug like this.
 
@@ -404,7 +407,9 @@
 How do we express a constant representing the largest value that fits in a `uint`?
 If we were talking about `uint32` rather than `uint`, we could write
 
+{{raw `
 	const MaxUint32 = 1<<32 - 1
+`}}
 
 but we want `uint`, not `uint32`.
 The `int` and `uint` types have equal unspecified numbers of bits, either 32 or 64.
@@ -416,24 +421,24 @@
 largest unsigned integer.
 We therefore might think we could write
 
-.play -edit constants/exercise1.go /const/
+{{play "constants/exercise1.go" `/const/`}}
 
 but that is illegal because -1 cannot be represented by an unsigned variable;
 `-1` is not in the range of unsigned values.
 A conversion won't help either, for the same reason:
 
-.play -edit constants/exercise2.go /const/
+{{play "constants/exercise2.go" `/const/`}}
 
 Even though at run-time a value of -1 can be converted to an unsigned integer, the rules
 for constant [conversions](https://golang.org/ref/spec#Conversions) forbid this kind of coercion at compile time.
 That is to say, this works:
 
-.play -edit constants/exercise3.go /START/,/STOP/
+{{play "constants/exercise3.go" `/START/` `/STOP/`}}
 
 but only because `v` is a variable; if we made `v` a constant,
 even an untyped constant, we'd be back in forbidden territory:
 
-.play -edit constants/exercise4.go /START/,/STOP/
+{{play "constants/exercise4.go" `/START/` `/STOP/`}}
 
 We return to our previous approach, but instead of `-1` we try `^0`,
 the bitwise negation of an arbitrary number of zero bits.
@@ -441,7 +446,7 @@
 In the space of numeric values,
 `^0` represents an infinite number of ones, so we lose information if we assign that to any fixed-size integer:
 
-.play -edit constants/exercise5.go /const/
+{{play "constants/exercise5.go" `/const/`}}
 
 How then do we represent the largest unsigned integer as a constant?
 
@@ -454,7 +459,7 @@
 Therefore we don't flip the bits of the untyped constant `0`, we flip the bits of the typed constant `uint(0)`.
 Here, then, is our constant:
 
-.play -edit constants/exercise6.go /START/,/STOP/
+{{play "constants/exercise6.go" `/START/` `/STOP/`}}
 
 Whatever the number of bits it takes to represent a `uint` in the current execution environment
 (on the [playground](https://blog.golang.org/playground), it's 32),
@@ -485,13 +490,13 @@
 Therefore, although they have different implicit default types,
 written as untyped constants they can be assigned to a variable of any numeric type:
 
-.play -edit constants/numbers1.go /START/,/STOP/
+{{play "constants/numbers1.go" `/START/` `/STOP/`}}
 
 The output from this snippet is: `1 1 1 1 1 (1+0i) 1`.
 
 You can even do nutty stuff like
 
-.play -edit constants/numbers2.go /START/,/STOP/
+{{play "constants/numbers2.go" `/START/` `/STOP/`}}
 
 which yields 145.5, which is pointless except to prove a point.
 
diff --git a/blog/_content/constants/bool.go b/go.dev/_content/blog/constants/bool.go
similarity index 100%
rename from blog/_content/constants/bool.go
rename to go.dev/_content/blog/constants/bool.go
diff --git a/blog/_content/constants/complex1.go b/go.dev/_content/blog/constants/complex1.go
similarity index 100%
rename from blog/_content/constants/complex1.go
rename to go.dev/_content/blog/constants/complex1.go
diff --git a/blog/_content/constants/complex2.go b/go.dev/_content/blog/constants/complex2.go
similarity index 100%
rename from blog/_content/constants/complex2.go
rename to go.dev/_content/blog/constants/complex2.go
diff --git a/blog/_content/constants/complex3.go b/go.dev/_content/blog/constants/complex3.go
similarity index 100%
rename from blog/_content/constants/complex3.go
rename to go.dev/_content/blog/constants/complex3.go
diff --git a/blog/_content/constants/default1.go b/go.dev/_content/blog/constants/default1.go
similarity index 100%
rename from blog/_content/constants/default1.go
rename to go.dev/_content/blog/constants/default1.go
diff --git a/blog/_content/constants/default2.go b/go.dev/_content/blog/constants/default2.go
similarity index 100%
rename from blog/_content/constants/default2.go
rename to go.dev/_content/blog/constants/default2.go
diff --git a/blog/_content/constants/default3.go b/go.dev/_content/blog/constants/default3.go
similarity index 100%
rename from blog/_content/constants/default3.go
rename to go.dev/_content/blog/constants/default3.go
diff --git a/blog/_content/constants/exercise1.go b/go.dev/_content/blog/constants/exercise1.go
similarity index 100%
rename from blog/_content/constants/exercise1.go
rename to go.dev/_content/blog/constants/exercise1.go
diff --git a/blog/_content/constants/exercise2.go b/go.dev/_content/blog/constants/exercise2.go
similarity index 100%
rename from blog/_content/constants/exercise2.go
rename to go.dev/_content/blog/constants/exercise2.go
diff --git a/blog/_content/constants/exercise3.go b/go.dev/_content/blog/constants/exercise3.go
similarity index 100%
rename from blog/_content/constants/exercise3.go
rename to go.dev/_content/blog/constants/exercise3.go
diff --git a/blog/_content/constants/exercise4.go b/go.dev/_content/blog/constants/exercise4.go
similarity index 100%
rename from blog/_content/constants/exercise4.go
rename to go.dev/_content/blog/constants/exercise4.go
diff --git a/blog/_content/constants/exercise5.go b/go.dev/_content/blog/constants/exercise5.go
similarity index 100%
rename from blog/_content/constants/exercise5.go
rename to go.dev/_content/blog/constants/exercise5.go
diff --git a/blog/_content/constants/exercise6.go b/go.dev/_content/blog/constants/exercise6.go
similarity index 100%
rename from blog/_content/constants/exercise6.go
rename to go.dev/_content/blog/constants/exercise6.go
diff --git a/blog/_content/constants/float1.go b/go.dev/_content/blog/constants/float1.go
similarity index 100%
rename from blog/_content/constants/float1.go
rename to go.dev/_content/blog/constants/float1.go
diff --git a/blog/_content/constants/float2.go b/go.dev/_content/blog/constants/float2.go
similarity index 100%
rename from blog/_content/constants/float2.go
rename to go.dev/_content/blog/constants/float2.go
diff --git a/blog/_content/constants/float3.go b/go.dev/_content/blog/constants/float3.go
similarity index 100%
rename from blog/_content/constants/float3.go
rename to go.dev/_content/blog/constants/float3.go
diff --git a/blog/_content/constants/float4.go b/go.dev/_content/blog/constants/float4.go
similarity index 100%
rename from blog/_content/constants/float4.go
rename to go.dev/_content/blog/constants/float4.go
diff --git a/blog/_content/constants/float5.go b/go.dev/_content/blog/constants/float5.go
similarity index 100%
rename from blog/_content/constants/float5.go
rename to go.dev/_content/blog/constants/float5.go
diff --git a/blog/_content/constants/int1.go b/go.dev/_content/blog/constants/int1.go
similarity index 100%
rename from blog/_content/constants/int1.go
rename to go.dev/_content/blog/constants/int1.go
diff --git a/blog/_content/constants/int2.go b/go.dev/_content/blog/constants/int2.go
similarity index 100%
rename from blog/_content/constants/int2.go
rename to go.dev/_content/blog/constants/int2.go
diff --git a/blog/_content/constants/int3.go b/go.dev/_content/blog/constants/int3.go
similarity index 100%
rename from blog/_content/constants/int3.go
rename to go.dev/_content/blog/constants/int3.go
diff --git a/blog/_content/constants/int4.go b/go.dev/_content/blog/constants/int4.go
similarity index 100%
rename from blog/_content/constants/int4.go
rename to go.dev/_content/blog/constants/int4.go
diff --git a/blog/_content/constants/numbers1.go b/go.dev/_content/blog/constants/numbers1.go
similarity index 100%
rename from blog/_content/constants/numbers1.go
rename to go.dev/_content/blog/constants/numbers1.go
diff --git a/blog/_content/constants/numbers2.go b/go.dev/_content/blog/constants/numbers2.go
similarity index 100%
rename from blog/_content/constants/numbers2.go
rename to go.dev/_content/blog/constants/numbers2.go
diff --git a/blog/_content/constants/string1.go b/go.dev/_content/blog/constants/string1.go
similarity index 100%
rename from blog/_content/constants/string1.go
rename to go.dev/_content/blog/constants/string1.go
diff --git a/blog/_content/constants/string2.go b/go.dev/_content/blog/constants/string2.go
similarity index 100%
rename from blog/_content/constants/string2.go
rename to go.dev/_content/blog/constants/string2.go
diff --git a/blog/_content/constants/string3.go b/go.dev/_content/blog/constants/string3.go
similarity index 100%
rename from blog/_content/constants/string3.go
rename to go.dev/_content/blog/constants/string3.go
diff --git a/blog/_content/constants/string4.go b/go.dev/_content/blog/constants/string4.go
similarity index 100%
rename from blog/_content/constants/string4.go
rename to go.dev/_content/blog/constants/string4.go
diff --git a/blog/_content/constants/syntax.go b/go.dev/_content/blog/constants/syntax.go
similarity index 100%
rename from blog/_content/constants/syntax.go
rename to go.dev/_content/blog/constants/syntax.go
diff --git a/blog/_content/context-and-structs.article b/go.dev/_content/blog/context-and-structs.md
similarity index 97%
rename from blog/_content/context-and-structs.article
rename to go.dev/_content/blog/context-and-structs.md
index a4242ef..0d8a7ab 100644
--- a/blog/_content/context-and-structs.article
+++ b/go.dev/_content/blog/context-and-structs.md
@@ -1,8 +1,13 @@
-# Contexts and structs
-24 Feb 2021
-Tags: context, cancelation, cancellation
-
-Jean de Klerk, Matt T. Proud
+---
+title: Contexts and structs
+date: 2021-02-24
+by:
+- Jean de Klerk, Matt T. Proud
+tags:
+- context
+- cancelation
+- cancellation
+---
 
 ## Introduction
 
diff --git a/blog/_content/context.article b/go.dev/_content/blog/context.md
similarity index 86%
rename from blog/_content/context.article
rename to go.dev/_content/blog/context.md
index 1d888f9..be63d61 100644
--- a/blog/_content/context.article
+++ b/go.dev/_content/blog/context.md
@@ -1,9 +1,15 @@
-# Go Concurrency Patterns: Context
-29 Jul 2014
-Tags: concurrency, cancelation, cancellation, context
-Summary: An introduction to the Go context package.
-
-Sameer Ajmani
+---
+title: "Go Concurrency Patterns: Context"
+date: 2014-07-29
+by:
+- Sameer Ajmani
+tags:
+- concurrency
+- cancelation
+- cancellation
+- context
+summary: An introduction to the Go context package.
+---
 
 ## Introduction
 
@@ -29,7 +35,7 @@
 
 The core of the `context` package is the `Context` type:
 
-.code context/interface.go /A Context/,/^}/
+{{code "context/interface.go" `/A Context/` `/^}/`}}
 
 (This description is condensed; the
 [godoc](https://golang.org/pkg/context) is authoritative.)
@@ -69,7 +75,7 @@
 
 `Background` is the root of any `Context` tree; it is never canceled:
 
-.code context/interface.go /Background returns/,/func Background/
+{{code "context/interface.go" `/Background returns/` `/func Background/`}}
 
 `WithCancel` and `WithTimeout` return derived `Context` values that can be
 canceled sooner than the parent `Context`.
@@ -79,11 +85,11 @@
 replicas.
 `WithTimeout` is useful for setting a deadline on requests to backend servers:
 
-.code context/interface.go /WithCancel/,/func WithTimeout/
+{{code "context/interface.go" `/WithCancel/` `/func WithTimeout/`}}
 
 `WithValue` provides a way to associate request-scoped values with a `Context`:
 
-.code context/interface.go /WithValue/,/func WithValue/
+{{code "context/interface.go" `/WithValue/` `/func WithValue/`}}
 
 The best way to see how to use the `context` package is through a worked
 example.
@@ -113,22 +119,22 @@
 If the request includes the `timeout` URL parameter, the `Context` is canceled
 automatically when the timeout elapses:
 
-.code context/server/server.go /func handleSearch/,/defer cancel/
+{{code "context/server/server.go" `/func handleSearch/` `/defer cancel/`}}
 
 The handler extracts the query from the request and extracts the client's IP
 address by calling on the `userip` package.
 The client's IP address is needed for backend requests, so `handleSearch`
 attaches it to `ctx`:
 
-.code context/server/server.go /Check the search query/,/userip.NewContext/
+{{code "context/server/server.go" `/Check the search query/` `/userip.NewContext/`}}
 
 The handler calls `google.Search` with `ctx` and the `query`:
 
-.code context/server/server.go /Run the Google search/,/elapsed/
+{{code "context/server/server.go" `/Run the Google search/` `/elapsed/`}}
 
 If the search succeeds, the handler renders the results:
 
-.code context/server/server.go /resultsTemplate/,/}$/
+{{code "context/server/server.go" `/resultsTemplate/` `/(?m)}$/`}}
 
 ### Package userip
 
@@ -144,19 +150,19 @@
 To avoid key collisions, `userip` defines an unexported type `key` and uses
 a value of this type as the context key:
 
-.code context/userip/userip.go /The key type/,/const userIPKey/
+{{code "context/userip/userip.go" `/The key type/` `/const userIPKey/`}}
 
 `FromRequest` extracts a `userIP` value from an `http.Request`:
 
-.code context/userip/userip.go /func FromRequest/,/}/
+{{code "context/userip/userip.go" `/func FromRequest/` `/}/`}}
 
 `NewContext` returns a new `Context` that carries a provided `userIP` value:
 
-.code context/userip/userip.go /func NewContext/,/}/
+{{code "context/userip/userip.go" `/func NewContext/` `/}/`}}
 
 `FromContext` extracts a `userIP` from a `Context`:
 
-.code context/userip/userip.go /func FromContext/,/}/
+{{code "context/userip/userip.go" `/func FromContext/` `/}/`}}
 
 ### Package google
 
@@ -169,19 +175,19 @@
 The Google Web Search API request includes the search query and the user IP as
 query parameters:
 
-.code context/google/google.go /func Search/,/q.Encode/
+{{code "context/google/google.go" `/func Search/` `/q.Encode/`}}
 
 `Search` uses a helper function, `httpDo`, to issue the HTTP request and cancel
 it if `ctx.Done` is closed while the request or response is being processed.
 `Search` passes a closure to `httpDo` handle the HTTP response:
 
-.code context/google/google.go /var results/,/return results/
+{{code "context/google/google.go" `/var results/` `/return results/`}}
 
 The `httpDo` function runs the HTTP request and processes its response in a new
 goroutine.
 It cancels the request if `ctx.Done` is closed before the goroutine exits:
 
-.code context/google/google.go /func httpDo/,/^}/
+{{code "context/google/google.go" `/func httpDo/` `/^}/`}}
 
 ## Adapting code for Contexts
 
diff --git a/blog/_content/context/google/google.go b/go.dev/_content/blog/context/google/google.go
similarity index 100%
rename from blog/_content/context/google/google.go
rename to go.dev/_content/blog/context/google/google.go
diff --git a/blog/_content/context/gorilla/gorilla.go b/go.dev/_content/blog/context/gorilla/gorilla.go
similarity index 100%
rename from blog/_content/context/gorilla/gorilla.go
rename to go.dev/_content/blog/context/gorilla/gorilla.go
diff --git a/blog/_content/context/interface.go b/go.dev/_content/blog/context/interface.go
similarity index 100%
rename from blog/_content/context/interface.go
rename to go.dev/_content/blog/context/interface.go
diff --git a/blog/_content/context/server/server.go b/go.dev/_content/blog/context/server/server.go
similarity index 100%
rename from blog/_content/context/server/server.go
rename to go.dev/_content/blog/context/server/server.go
diff --git a/blog/_content/context/tomb/tomb.go b/go.dev/_content/blog/context/tomb/tomb.go
similarity index 100%
rename from blog/_content/context/tomb/tomb.go
rename to go.dev/_content/blog/context/tomb/tomb.go
diff --git a/blog/_content/context/userip/userip.go b/go.dev/_content/blog/context/userip/userip.go
similarity index 100%
rename from blog/_content/context/userip/userip.go
rename to go.dev/_content/blog/context/userip/userip.go
diff --git a/blog/_content/contributor-workshop.article b/go.dev/_content/blog/contributor-workshop.md
similarity index 92%
rename from blog/_content/contributor-workshop.article
rename to go.dev/_content/blog/contributor-workshop.md
index 1254bb9..6b5d47d 100644
--- a/blog/_content/contributor-workshop.article
+++ b/go.dev/_content/blog/contributor-workshop.md
@@ -1,15 +1,15 @@
-# Contribution Workshop
-9 Aug 2017
-Tags: community
-Summary: The Go contributor workshop trained new contributors at GopherCon.
-
-Steve Francia
-
-Cassandra Salisbury
-
-Matt Broberg
-
-Dmitri Shuralyov
+---
+title: Contribution Workshop
+date: 2017-08-09
+by:
+- Steve Francia
+- Cassandra Salisbury
+- Matt Broberg
+- Dmitri Shuralyov
+tags:
+- community
+summary: The Go contributor workshop trained new contributors at GopherCon.
+---
 
 ## Event Overview
 
@@ -39,15 +39,15 @@
 a change list (also known as a CL, similar to a pull request),
 amending a CL, or submitting a CL.
 
-.image contributor-workshop/image17.png
+{{image "contributor-workshop/image17.png"}}
 
 Brad Fitzpatrick, who stayed home from GopherCon this year, was ready and
 waiting to review all CLs submitted. He was so quick to review that many people
 thought he was an automated bot. Internally our team is now calling him
 "BradBot" mostly because we are in awe and a bit jealous.
 
-.image contributor-workshop/image9.jpg
-.image contributor-workshop/image6.png
+{{image "contributor-workshop/image9.jpg"}}
+{{image "contributor-workshop/image6.png"}}
 
 ### Impact
 
@@ -89,7 +89,7 @@
 [CL 48871](https://golang.org/cl/48871/),
 after which she tweeted:
 
-.image contributor-workshop/image19.png
+{{image "contributor-workshop/image19.png"}}
 
 Not only were some great improvements made, but most importantly, we narrowed
 the gap between the core Go team and the broader community members. Many people
@@ -97,9 +97,9 @@
 about the Go project. People in the community (in person, and on Twitter)
 remarked that felt welcome to participate in the project.
 
-.image contributor-workshop/image12.png
-.image contributor-workshop/image13.png
-.image contributor-workshop/image3.png
+{{image "contributor-workshop/image12.png"}}
+{{image "contributor-workshop/image13.png"}}
+{{image "contributor-workshop/image3.png"}}
 
 ### Future
 
@@ -134,7 +134,7 @@
 [a link](https://docs.google.com/presentation/d/1ap2fycBSgoo-jCswhK9lqgCIFroE1pYpsXC1ffYBCq4/edit#slide=id.p)
 to make it easy to follow.
 
-.image contributor-workshop/image16.png
+{{image "contributor-workshop/image16.png"}}
 
 The murmurs grew from a deep undercurrent to a resounding melody of voices,
 people were getting their computers set up with Go, they were skipping ahead to
@@ -145,7 +145,7 @@
 GitHub with slightly more advanced code review tools. We then went through
 GitHub vs Geritt terminology, so we had better understanding of the process.
 
-.image contributor-workshop/image10.png
+{{image "contributor-workshop/image10.png"}}
 
 Ok, now it was time to become a **freaking Go contributor**.
 
@@ -153,13 +153,13 @@
 we could track as a group how many points we could rack up based on the Gerrit
 score system.
 
-.image contributor-workshop/image7.png
+{{image "contributor-workshop/image7.png"}}
 
 Seeing your name pop up on the board and listening to everyone's excitement was
 intoxicating. It also invoked a sense of teamwork that lead to a feeling of
 inclusion and feeling like you were truly a part of the Go community.
 
-.image contributor-workshop/image11.png
+{{image "contributor-workshop/image11.png"}}
 
 In 6 steps a room of around 80 people were able to learn how to contribute to
 go within an hour. That's a feat!
@@ -246,8 +246,8 @@
 After a few back and forths, I officially had a contribute to Go! And if Jaana
 is right, it might be the first with emojis ✌️.
 
-.image contributor-workshop/image15.png
-.image contributor-workshop/image23.png
+{{image "contributor-workshop/image15.png"}}
+{{image "contributor-workshop/image23.png"}}
 
 ### Contributing, For Real
 
@@ -257,7 +257,7 @@
 me. And by "cruised around" I mean attempted to find a list of packages, then
 went to my source code to see what's around under the `go/src/` folder:
 
-.image contributor-workshop/image22.png
+{{image "contributor-workshop/image22.png"}}
 
 I decided to see what I can do in the `regexp` package, maybe out of love and
 fear of regex. Here's where I switched to the
@@ -266,7 +266,7 @@
 there I noticed that `QuoteMeta` was missing the same level of detailed examples
 other functions have (and I could use the practice using Gerrit).
 
-.image contributor-workshop/image1.png
+{{image "contributor-workshop/image1.png"}}
 
 I started looking at `go/src/regexp` to try to find where to add examples and I
 got lost pretty quickly. Lucky for me, [Francesc](https://twitter.com/francesc) was around that day. He walked
@@ -383,13 +383,13 @@
 
 ## Photos from the event
 
-.image contributor-workshop/image2.jpg
-.image contributor-workshop/image4.jpg
-.image contributor-workshop/image5.jpg
-.image contributor-workshop/image8.jpg
-.image contributor-workshop/image14.jpg
-.image contributor-workshop/image18.jpg
-.image contributor-workshop/image20.jpg
-.image contributor-workshop/image21.jpg
+{{image "contributor-workshop/image2.jpg"}}
+{{image "contributor-workshop/image4.jpg"}}
+{{image "contributor-workshop/image5.jpg"}}
+{{image "contributor-workshop/image8.jpg"}}
+{{image "contributor-workshop/image14.jpg"}}
+{{image "contributor-workshop/image18.jpg"}}
+{{image "contributor-workshop/image20.jpg"}}
+{{image "contributor-workshop/image21.jpg"}}
 
 Photos by Sameer Ajmani & Steve Francia
diff --git a/blog/_content/contributor-workshop/image1.png b/go.dev/_content/blog/contributor-workshop/image1.png
similarity index 100%
rename from blog/_content/contributor-workshop/image1.png
rename to go.dev/_content/blog/contributor-workshop/image1.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image10.png b/go.dev/_content/blog/contributor-workshop/image10.png
similarity index 100%
rename from blog/_content/contributor-workshop/image10.png
rename to go.dev/_content/blog/contributor-workshop/image10.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image11.png b/go.dev/_content/blog/contributor-workshop/image11.png
similarity index 100%
rename from blog/_content/contributor-workshop/image11.png
rename to go.dev/_content/blog/contributor-workshop/image11.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image12.png b/go.dev/_content/blog/contributor-workshop/image12.png
similarity index 100%
rename from blog/_content/contributor-workshop/image12.png
rename to go.dev/_content/blog/contributor-workshop/image12.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image13.png b/go.dev/_content/blog/contributor-workshop/image13.png
similarity index 100%
rename from blog/_content/contributor-workshop/image13.png
rename to go.dev/_content/blog/contributor-workshop/image13.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image14.jpg b/go.dev/_content/blog/contributor-workshop/image14.jpg
similarity index 100%
rename from blog/_content/contributor-workshop/image14.jpg
rename to go.dev/_content/blog/contributor-workshop/image14.jpg
Binary files differ
diff --git a/blog/_content/contributor-workshop/image15.png b/go.dev/_content/blog/contributor-workshop/image15.png
similarity index 100%
rename from blog/_content/contributor-workshop/image15.png
rename to go.dev/_content/blog/contributor-workshop/image15.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image16.png b/go.dev/_content/blog/contributor-workshop/image16.png
similarity index 100%
rename from blog/_content/contributor-workshop/image16.png
rename to go.dev/_content/blog/contributor-workshop/image16.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image17.png b/go.dev/_content/blog/contributor-workshop/image17.png
similarity index 100%
rename from blog/_content/contributor-workshop/image17.png
rename to go.dev/_content/blog/contributor-workshop/image17.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image18.jpg b/go.dev/_content/blog/contributor-workshop/image18.jpg
similarity index 100%
rename from blog/_content/contributor-workshop/image18.jpg
rename to go.dev/_content/blog/contributor-workshop/image18.jpg
Binary files differ
diff --git a/blog/_content/contributor-workshop/image19.png b/go.dev/_content/blog/contributor-workshop/image19.png
similarity index 100%
rename from blog/_content/contributor-workshop/image19.png
rename to go.dev/_content/blog/contributor-workshop/image19.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image2.jpg b/go.dev/_content/blog/contributor-workshop/image2.jpg
similarity index 100%
rename from blog/_content/contributor-workshop/image2.jpg
rename to go.dev/_content/blog/contributor-workshop/image2.jpg
Binary files differ
diff --git a/blog/_content/contributor-workshop/image20.jpg b/go.dev/_content/blog/contributor-workshop/image20.jpg
similarity index 100%
rename from blog/_content/contributor-workshop/image20.jpg
rename to go.dev/_content/blog/contributor-workshop/image20.jpg
Binary files differ
diff --git a/blog/_content/contributor-workshop/image21.jpg b/go.dev/_content/blog/contributor-workshop/image21.jpg
similarity index 100%
rename from blog/_content/contributor-workshop/image21.jpg
rename to go.dev/_content/blog/contributor-workshop/image21.jpg
Binary files differ
diff --git a/blog/_content/contributor-workshop/image22.png b/go.dev/_content/blog/contributor-workshop/image22.png
similarity index 100%
rename from blog/_content/contributor-workshop/image22.png
rename to go.dev/_content/blog/contributor-workshop/image22.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image23.png b/go.dev/_content/blog/contributor-workshop/image23.png
similarity index 100%
rename from blog/_content/contributor-workshop/image23.png
rename to go.dev/_content/blog/contributor-workshop/image23.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image3.png b/go.dev/_content/blog/contributor-workshop/image3.png
similarity index 100%
rename from blog/_content/contributor-workshop/image3.png
rename to go.dev/_content/blog/contributor-workshop/image3.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image4.jpg b/go.dev/_content/blog/contributor-workshop/image4.jpg
similarity index 100%
rename from blog/_content/contributor-workshop/image4.jpg
rename to go.dev/_content/blog/contributor-workshop/image4.jpg
Binary files differ
diff --git a/blog/_content/contributor-workshop/image5.jpg b/go.dev/_content/blog/contributor-workshop/image5.jpg
similarity index 100%
rename from blog/_content/contributor-workshop/image5.jpg
rename to go.dev/_content/blog/contributor-workshop/image5.jpg
Binary files differ
diff --git a/blog/_content/contributor-workshop/image6.png b/go.dev/_content/blog/contributor-workshop/image6.png
similarity index 100%
rename from blog/_content/contributor-workshop/image6.png
rename to go.dev/_content/blog/contributor-workshop/image6.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image7.png b/go.dev/_content/blog/contributor-workshop/image7.png
similarity index 100%
rename from blog/_content/contributor-workshop/image7.png
rename to go.dev/_content/blog/contributor-workshop/image7.png
Binary files differ
diff --git a/blog/_content/contributor-workshop/image8.jpg b/go.dev/_content/blog/contributor-workshop/image8.jpg
similarity index 100%
rename from blog/_content/contributor-workshop/image8.jpg
rename to go.dev/_content/blog/contributor-workshop/image8.jpg
Binary files differ
diff --git a/blog/_content/contributor-workshop/image9.jpg b/go.dev/_content/blog/contributor-workshop/image9.jpg
similarity index 100%
rename from blog/_content/contributor-workshop/image9.jpg
rename to go.dev/_content/blog/contributor-workshop/image9.jpg
Binary files differ
diff --git a/blog/_content/contributors-summit-2019.article b/go.dev/_content/blog/contributors-summit-2019.md
similarity index 98%
rename from blog/_content/contributors-summit-2019.article
rename to go.dev/_content/blog/contributors-summit-2019.md
index ad3aeee..731d53d 100644
--- a/blog/_content/contributors-summit-2019.article
+++ b/go.dev/_content/blog/contributors-summit-2019.md
@@ -1,9 +1,12 @@
-# Contributors Summit 2019
-15 Aug 2019
-Tags: community
-Summary: Reporting from the Go Contributor Summit at GopherCon 2019.
-
-Carmen Andoh and contributors
+---
+title: Contributors Summit 2019
+date: 2019-08-15
+by:
+- Carmen Andoh and contributors
+tags:
+- community
+summary: Reporting from the Go Contributor Summit at GopherCon 2019.
+---
 
 ## Introduction
 
@@ -16,7 +19,7 @@
 We asked five contributors to write about their experience
 in various discussions at this year’s summit.
 
-.image contributors-summit-2019/group.jpg _ 800
+{{image "contributors-summit-2019/group.jpg" 800}}
 
 _(Photo by Steve Francia.)_
 
diff --git a/blog/_content/contributors-summit-2019/group.jpg b/go.dev/_content/blog/contributors-summit-2019/group.jpg
similarity index 100%
rename from blog/_content/contributors-summit-2019/group.jpg
rename to go.dev/_content/blog/contributors-summit-2019/group.jpg
Binary files differ
diff --git a/blog/_content/contributors-summit.article b/go.dev/_content/blog/contributors-summit.md
similarity index 93%
rename from blog/_content/contributors-summit.article
rename to go.dev/_content/blog/contributors-summit.md
index 86e6d94..022702c 100644
--- a/blog/_content/contributors-summit.article
+++ b/go.dev/_content/blog/contributors-summit.md
@@ -1,9 +1,12 @@
-# Contributors Summit
-3 Aug 2017
-Tags: community
-Summary: Reporting from the Go Contributor Summit at GopherCon 2017.
-
-Sam Whited
+---
+title: Contributors Summit
+date: 2017-08-03
+by:
+- Sam Whited
+tags:
+- community
+summary: Reporting from the Go Contributor Summit at GopherCon 2017.
+---
 
 ## Introduction
 
@@ -160,10 +163,10 @@
 Going forward, we hope to do more frequent events like this to facilitate
 discourse and a sense of community.
 
-.image contributors-summit/IMG_20170712_145844.jpg
-.image contributors-summit/IMG_20170712_145854.jpg
-.image contributors-summit/IMG_20170712_145905.jpg
-.image contributors-summit/IMG_20170712_145911.jpg
-.image contributors-summit/IMG_20170712_145950.jpg
+{{image "contributors-summit/IMG_20170712_145844.jpg"}}
+{{image "contributors-summit/IMG_20170712_145854.jpg"}}
+{{image "contributors-summit/IMG_20170712_145905.jpg"}}
+{{image "contributors-summit/IMG_20170712_145911.jpg"}}
+{{image "contributors-summit/IMG_20170712_145950.jpg"}}
 
 Photos by Steve Francia
diff --git a/blog/_content/contributors-summit/IMG_20170712_145844.jpg b/go.dev/_content/blog/contributors-summit/IMG_20170712_145844.jpg
similarity index 100%
rename from blog/_content/contributors-summit/IMG_20170712_145844.jpg
rename to go.dev/_content/blog/contributors-summit/IMG_20170712_145844.jpg
Binary files differ
diff --git a/blog/_content/contributors-summit/IMG_20170712_145854.jpg b/go.dev/_content/blog/contributors-summit/IMG_20170712_145854.jpg
similarity index 100%
rename from blog/_content/contributors-summit/IMG_20170712_145854.jpg
rename to go.dev/_content/blog/contributors-summit/IMG_20170712_145854.jpg
Binary files differ
diff --git a/blog/_content/contributors-summit/IMG_20170712_145905.jpg b/go.dev/_content/blog/contributors-summit/IMG_20170712_145905.jpg
similarity index 100%
rename from blog/_content/contributors-summit/IMG_20170712_145905.jpg
rename to go.dev/_content/blog/contributors-summit/IMG_20170712_145905.jpg
Binary files differ
diff --git a/blog/_content/contributors-summit/IMG_20170712_145911.jpg b/go.dev/_content/blog/contributors-summit/IMG_20170712_145911.jpg
similarity index 100%
rename from blog/_content/contributors-summit/IMG_20170712_145911.jpg
rename to go.dev/_content/blog/contributors-summit/IMG_20170712_145911.jpg
Binary files differ
diff --git a/blog/_content/contributors-summit/IMG_20170712_145950.jpg b/go.dev/_content/blog/contributors-summit/IMG_20170712_145950.jpg
similarity index 100%
rename from blog/_content/contributors-summit/IMG_20170712_145950.jpg
rename to go.dev/_content/blog/contributors-summit/IMG_20170712_145950.jpg
Binary files differ
diff --git a/blog/_content/cover.article b/go.dev/_content/blog/cover.md
similarity index 96%
rename from blog/_content/cover.article
rename to go.dev/_content/blog/cover.md
index 7e9e629..7142302 100644
--- a/blog/_content/cover.article
+++ b/go.dev/_content/blog/cover.md
@@ -1,9 +1,14 @@
-# The cover story
-2 Dec 2013
-Tags: tools, coverage, testing
-Summary: Introducing Go 1.12's code coverage tool.
-
-Rob Pike
+---
+title: The cover story
+date: 2013-12-02
+by:
+- Rob Pike
+tags:
+- tools
+- coverage
+- testing
+summary: Introducing Go 1.12's code coverage tool.
+---
 
 ## Introduction
 
@@ -101,11 +106,11 @@
 
 Here's an example. Say we have a simple, one-file package like this:
 
-.code cover/pkg.go
+{{code "cover/pkg.go"}}
 
 and this test:
 
-.code cover/pkg_test.go
+{{code "cover/pkg_test.go"}}
 
 To get the test coverage for the package,
 we run the test with coverage enabled by providing the `-cover` flag to `go` `test`:
@@ -123,7 +128,7 @@
 with the distribution, to rewrite the source code before compilation. Here's what the rewritten
 `Size` function looks like:
 
-.code cover/pkg.cover /func/,/^}/
+{{code "cover/pkg.cover" `/func/` `/^}/`}}
 
 Each executable section of the program is annotated with an assignment statement that,
 when executed, records that that section ran.
@@ -171,7 +176,7 @@
 uncovered (red), and uninstrumented (grey) source.
 Here's a screen dump:
 
-.image cover/set.png
+{{image "cover/set.png"}}
 
 With this presentation, it's obvious what's wrong: we neglected to test several
 of the cases!
@@ -230,7 +235,7 @@
 
 Here's what the `pad` function looks like in that presentation:
 
-.image cover/count.png
+{{image "cover/count.png"}}
 
 Notice how the intensity of the green changes. Brighter-green
 statements have higher execution counts; less saturated greens
diff --git a/blog/_content/cover/count.png b/go.dev/_content/blog/cover/count.png
similarity index 100%
rename from blog/_content/cover/count.png
rename to go.dev/_content/blog/cover/count.png
Binary files differ
diff --git a/blog/_content/cover/pkg.cover b/go.dev/_content/blog/cover/pkg.cover
similarity index 100%
rename from blog/_content/cover/pkg.cover
rename to go.dev/_content/blog/cover/pkg.cover
diff --git a/blog/_content/cover/pkg.go b/go.dev/_content/blog/cover/pkg.go
similarity index 100%
rename from blog/_content/cover/pkg.go
rename to go.dev/_content/blog/cover/pkg.go
diff --git a/blog/_content/cover/pkg_test.go b/go.dev/_content/blog/cover/pkg_test.go
similarity index 100%
rename from blog/_content/cover/pkg_test.go
rename to go.dev/_content/blog/cover/pkg_test.go
diff --git a/blog/_content/cover/set.png b/go.dev/_content/blog/cover/set.png
similarity index 100%
rename from blog/_content/cover/set.png
rename to go.dev/_content/blog/cover/set.png
Binary files differ
diff --git a/blog/_content/cwg.article b/go.dev/_content/blog/cwg.md
similarity index 88%
rename from blog/_content/cwg.article
rename to go.dev/_content/blog/cwg.md
index 0e17def..9c9fcb2 100644
--- a/blog/_content/cwg.article
+++ b/go.dev/_content/blog/cwg.md
@@ -1,11 +1,12 @@
-# Community Outreach Working Group
-5 Sep 2017
-Tags: community
-Summary: Announcing the Go Community Outreach Working Group (CWG).
-OldURL: /community-outreach-working-group
-
-Steve Francia & Cassandra Salisbury
-spf@golang.org
+---
+title: Community Outreach Working Group
+date: 2017-09-05
+by:
+- Steve Francia & Cassandra Salisbury
+tags:
+- community
+summary: Announcing the Go Community Outreach Working Group (CWG).
+---
 
 ## Announcing the Go Community Outreach Working Group
 
@@ -49,7 +50,7 @@
 primary initiatives. Each project has a variety of [issues](https://github.com/golang/cwg/issues) tied to them
 with assignees from our Leadership team and [our members](https://github.com/golang/cwg/issues/15).
 
-.image cwg/project.png
+{{image "cwg/project.png"}}
 
 If you’d like to get involved, we encourage you to comment on the issue
 that interests you or [submit an issue](https://github.com/golang/cwg/issues/new) yourself!
diff --git a/blog/_content/cwg/project.png b/go.dev/_content/blog/cwg/project.png
similarity index 100%
rename from blog/_content/cwg/project.png
rename to go.dev/_content/blog/cwg/project.png
Binary files differ
diff --git a/blog/_content/debug-gdb.article b/go.dev/_content/blog/debug-gdb.md
similarity index 74%
rename from blog/_content/debug-gdb.article
rename to go.dev/_content/blog/debug-gdb.md
index ff24c4f..148c5d6 100644
--- a/blog/_content/debug-gdb.article
+++ b/go.dev/_content/blog/debug-gdb.md
@@ -1,12 +1,15 @@
-# Debugging Go programs with the GNU Debugger
-30 Oct 2011
-Tags: debug, gdb, technical
-Summary: Announcing a new article about debugging Go programs with GDB.
-OldURL: /debugging-go-programs-with-gnu-debugger
+---
+title: Debugging Go programs with the GNU Debugger
+date: 2011-10-30
+by:
+- Andrew Gerrand
+tags:
+- debug
+- gdb
+- technical
+summary: Announcing a new article about debugging Go programs with GDB.
+---
 
-Andrew Gerrand
-
-##
 
 Last year we [reported](https://blog.golang.org/2010/11/debugging-go-code-status-report.html)
 that Go's [gc](https://golang.org/cmd/gc/)/[ld](https://golang.org/cmd/6l/)
diff --git a/blog/_content/debug-opt.article b/go.dev/_content/blog/debug-opt.md
similarity index 94%
rename from blog/_content/debug-opt.article
rename to go.dev/_content/blog/debug-opt.md
index 002181b..92e01bd 100644
--- a/blog/_content/debug-opt.article
+++ b/go.dev/_content/blog/debug-opt.md
@@ -1,10 +1,13 @@
-# Debugging what you deploy in Go 1.12
-21 Mar 2019
-Tags: debug, technical
-Summary: Go 1.12 improves support for debugging optimized binaries.
-OldURL: /debugging-what-you-deploy
-
-David Chase
+---
+title: Debugging what you deploy in Go 1.12
+date: 2019-03-21
+by:
+- David Chase
+tags:
+- debug
+- technical
+summary: Go 1.12 improves support for debugging optimized binaries.
+---
 
 ## Introduction
 
@@ -66,7 +69,7 @@
 This shows an example of stepping through a simple function in a debugger in 1.10,
 with flaws (skipped and repeated lines) highlighted by red arrows.
 
-.image debug-opt/stepping.svg _ 450
+{{image "debug-opt/stepping.svg" 450}}
 
 Flaws like this make it easy to lose track of where you are when stepping
 through a program and interfere with hitting breakpoints.
diff --git a/blog/_content/debug-opt/stepping.graffle b/go.dev/_content/blog/debug-opt/stepping.graffle
similarity index 100%
rename from blog/_content/debug-opt/stepping.graffle
rename to go.dev/_content/blog/debug-opt/stepping.graffle
Binary files differ
diff --git a/blog/_content/debug-opt/stepping.svg b/go.dev/_content/blog/debug-opt/stepping.svg
similarity index 100%
rename from blog/_content/debug-opt/stepping.svg
rename to go.dev/_content/blog/debug-opt/stepping.svg
diff --git a/blog/_content/debug-status.article b/go.dev/_content/blog/debug-status.md
similarity index 93%
rename from blog/_content/debug-status.article
rename to go.dev/_content/blog/debug-status.md
index 1f5416b..a3a644b 100644
--- a/blog/_content/debug-status.article
+++ b/go.dev/_content/blog/debug-status.md
@@ -1,12 +1,14 @@
-# Debugging Go code (a status report)
-2 Nov 2010
-Tags: debug, gdb
-Summary: What works and what doesn't when debugging Go programs with GDB.
-OldURL: /debugging-go-code-status-report
+---
+title: Debugging Go code (a status report)
+date: 2010-11-02
+by:
+- Luuk van Dijk
+tags:
+- debug
+- gdb
+summary: What works and what doesn't when debugging Go programs with GDB.
+---
 
-Luuk van Dijk
-
-##
 
 When it comes to debugging, nothing beats a few strategic print statements
 to inspect variables or a well-placed panic to obtain a stack trace.
diff --git a/go.dev/_content/blog/debugging-go-code-status-report.md b/go.dev/_content/blog/debugging-go-code-status-report.md
new file mode 100644
index 0000000..1bacc88
--- /dev/null
+++ b/go.dev/_content/blog/debugging-go-code-status-report.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/debug-status
+---
diff --git a/go.dev/_content/blog/debugging-go-programs-with-gnu-debugger.md b/go.dev/_content/blog/debugging-go-programs-with-gnu-debugger.md
new file mode 100644
index 0000000..0df5ba3
--- /dev/null
+++ b/go.dev/_content/blog/debugging-go-programs-with-gnu-debugger.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/debug-gdb
+---
diff --git a/go.dev/_content/blog/debugging-what-you-deploy.md b/go.dev/_content/blog/debugging-what-you-deploy.md
new file mode 100644
index 0000000..9776292
--- /dev/null
+++ b/go.dev/_content/blog/debugging-what-you-deploy.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/debug-opt
+---
diff --git a/blog/_content/declaration-syntax.article b/go.dev/_content/blog/declaration-syntax.md
similarity index 96%
rename from blog/_content/declaration-syntax.article
rename to go.dev/_content/blog/declaration-syntax.md
index f1d0574..6317ee2 100644
--- a/blog/_content/declaration-syntax.article
+++ b/go.dev/_content/blog/declaration-syntax.md
@@ -1,10 +1,14 @@
-# Go's Declaration Syntax
-7 Jul 2010
-Tags: c, syntax, ethos
-Summary: Why Go's declaration syntax doesn't look like, and is much simpler than, C's.
-OldURL: /gos-declaration-syntax
-
-Rob Pike
+---
+title: Go's Declaration Syntax
+date: 2010-07-07
+by:
+- Rob Pike
+tags:
+- c
+- syntax
+- ethos
+summary: Why Go's declaration syntax doesn't look like, and is much simpler than, C's.
+---
 
 ## Introduction
 
diff --git a/go.dev/_content/blog/default.tmpl b/go.dev/_content/blog/default.tmpl
new file mode 100644
index 0000000..b4de71b
--- /dev/null
+++ b/go.dev/_content/blog/default.tmpl
@@ -0,0 +1,71 @@
+{{define "layout"}}
+<div id="blog"><div id="content">
+  <div id="content">
+
+    <div class="Article" data-slug="{{.URL}}">
+    {{if ne .URL "/blog/"}}
+    <h1 class="small"><a href="/blog/">The Go Blog</a></h1>
+    {{end}}
+
+    <h1>{{.title}}</h1>
+      {{if or .by .date}}
+      <p class="author">
+      {{with .by}}{{by .}}<br>{{end}}
+      {{.date.Format "2 January 2006"}}
+      </p>
+      {{end}}
+      {{.Content}}
+    </div>
+
+    {{if and (ne .URL "/blog/") (ne .URL "/blog/all")}}
+    <div class="Article prevnext">
+    {{$list := newest (pages "/blog/*.md")}}
+    {{range $i, $p := $list}}
+      {{if eq $p.URL $.URL}}
+        <p>
+        {{if and (gt $i 0) (index $list (sub $i 1)).date}}
+          {{with index $list (sub $i 1)}}
+            <b>Next article: </b><a href="{{.URL}}">{{.title}}</a><br>
+          {{end}}
+        {{end}}
+        {{if and (lt (add $i 1) (len $list)) (index $list (add $i 1)).date}}
+          {{with index $list (add $i 1)}}
+            <b>Previous article: </b><a href="{{.URL}}">{{.title}}</a><br>
+          {{end}}
+        {{end}}
+        <b><a href="/blog/all">Blog Index</a></b>
+      {{end}}
+    {{end}}
+    </div>
+    {{end}}
+
+  </div><!-- #content -->
+</div>
+
+<script src="/js/jquery.js"></script>
+<script src="/js/playground.js"></script>
+<script src="/js/play.js"></script>
+<script src="/js/godocs.js"></script>
+{{end}}
+
+{{define "by list" -}}
+  {{if eq (len .list) 1 -}}
+  {{index .list 0 -}}
+  {{else if eq (len .list) 2 -}}
+  {{index .list 0}} and {{index .list 1 -}}
+  {{else -}}
+  {{range first (sub (len .list) 1) .list}}{{.}}, {{end}} and {{index .list (sub (len .list) 1) -}}
+  {{end -}}
+{{end}}
+
+{{define "image url width? height? alt?"}}
+<div class="image">
+  <img src="{{.url}}"{{with .width}} width="{{.}}"{{end}}{{with .height}} height="{{.}}"{{end}} alt="{{.alt}}">
+</div>
+{{end}}
+
+{{define "video url width? height?"}}
+<div class="iframe">
+  <iframe src="{{.url}}" width="{{or .width 560}}" height="{{or .height 315}}" frameborder="0" allowfullscreen mozallowfullscreen webkitallowfullscreen></iframe>
+</div>
+{{end}}
diff --git a/blog/_content/defer-panic-and-recover.article b/go.dev/_content/blog/defer-panic-and-recover.md
similarity index 95%
rename from blog/_content/defer-panic-and-recover.article
rename to go.dev/_content/blog/defer-panic-and-recover.md
index 93431a3..8d927cf 100644
--- a/blog/_content/defer-panic-and-recover.article
+++ b/go.dev/_content/blog/defer-panic-and-recover.md
@@ -1,11 +1,17 @@
-# Defer, Panic, and Recover
-4 Aug 2010
-Tags: defer, panic, recover, technical, function
-Summary: An introduction to the Go's defer, panic, and recover control flow mechanisms.
+---
+title: Defer, Panic, and Recover
+date: 2010-08-04
+by:
+- Andrew Gerrand
+tags:
+- defer
+- panic
+- recover
+- technical
+- function
+summary: An introduction to the Go's defer, panic, and recover control flow mechanisms.
+---
 
-Andrew Gerrand
-
-##
 
 Go has the usual mechanisms for control flow:
 if, for, switch, goto.
@@ -81,11 +87,13 @@
 
 This function prints "3210":
 
+{{raw `
 	func b() {
 	    for i := 0; i < 4; i++ {
 	        defer fmt.Print(i)
 	    }
 	}
+`}}
 
 3. _Deferred functions may read and assign to the returning function's named return values._
 
diff --git a/blog/_content/developer-experience.article b/go.dev/_content/blog/developer-experience.md
similarity index 88%
rename from blog/_content/developer-experience.article
rename to go.dev/_content/blog/developer-experience.md
index 73254f5..5543972 100644
--- a/blog/_content/developer-experience.article
+++ b/go.dev/_content/blog/developer-experience.md
@@ -1,10 +1,11 @@
-# Introducing the Developer Experience Working Group
-10 Apr 2017
-Summary: Announcing the Developer eXperience Working Group (DXWG).
+---
+title: Introducing the Developer Experience Working Group
+date: 2017-04-10
+by:
+- The Developer Experience Working Group
+summary: Announcing the Developer eXperience Working Group (DXWG).
+---
 
-The Developer Experience Working Group
-
-##
 
 Over the last several years, Go's audience has shifted from early
 adopters to mainstream users. Today, our users come from a wide
diff --git a/blog/_content/docker.article b/go.dev/_content/blog/docker.md
similarity index 96%
rename from blog/_content/docker.article
rename to go.dev/_content/blog/docker.md
index d0be85c..908940c 100644
--- a/blog/_content/docker.article
+++ b/go.dev/_content/blog/docker.md
@@ -1,8 +1,10 @@
-# Deploying Go servers with Docker
-26 Sep 2014
-Summary: How to use Docker's new official base images for Go.
-
-Andrew Gerrand
+---
+title: Deploying Go servers with Docker
+date: 2014-09-26
+by:
+- Andrew Gerrand
+summary: How to use Docker's new official base images for Go.
+---
 
 ## Introduction
 
@@ -93,7 +95,7 @@
 With the container running, open `http://localhost:6060/` in a web browser and
 you should see something like this:
 
-.image docker/outyet.png
+{{image "docker/outyet.png"}}
 
 (If your docker daemon is running on another machine (or in a virtual machine),
 you should replace `localhost` with the address of that machine. If you're
diff --git a/blog/_content/docker/outyet.png b/go.dev/_content/blog/docker/outyet.png
similarity index 100%
rename from blog/_content/docker/outyet.png
rename to go.dev/_content/blog/docker/outyet.png
Binary files differ
diff --git a/blog/_content/error-handling-and-go.article b/go.dev/_content/blog/error-handling-and-go.md
similarity index 97%
rename from blog/_content/error-handling-and-go.article
rename to go.dev/_content/blog/error-handling-and-go.md
index 092addc..9015c3b 100644
--- a/blog/_content/error-handling-and-go.article
+++ b/go.dev/_content/blog/error-handling-and-go.md
@@ -1,9 +1,15 @@
-# Error handling and Go
-12 Jul 2011
-Tags: error, interface, type, technical
-Summary: An introduction to Go errors.
-
-Andrew Gerrand
+---
+title: Error handling and Go
+date: 2011-07-12
+by:
+- Andrew Gerrand
+tags:
+- error
+- interface
+- type
+- technical
+summary: An introduction to Go errors.
+---
 
 ## Introduction
 
@@ -64,12 +70,14 @@
 
 Here's how you might use `errors.New`:
 
+{{raw `
 	func Sqrt(f float64) (float64, error) {
 	    if f < 0 {
 	        return 0, errors.New("math: square root of negative number")
 	    }
 	    // implementation
 	}
+`}}
 
 A caller passing a negative argument to `Sqrt` receives a non-nil `error`
 value (whose concrete representation is an `errors.errorString` value).
@@ -93,9 +101,11 @@
 It formats a string according to `Printf`'s rules and returns it as an `error`
 created by `errors.New`.
 
+{{raw `
 	if f < 0 {
 	    return 0, fmt.Errorf("math: square root of negative number %g", f)
 	}
+`}}
 
 In many cases `fmt.Errorf` is good enough,
 but since `error` is an interface, you can use arbitrary data structures as error values,
diff --git a/blog/_content/errors-are-values.article b/go.dev/_content/blog/errors-are-values.md
similarity index 97%
rename from blog/_content/errors-are-values.article
rename to go.dev/_content/blog/errors-are-values.md
index 761c716..3f931f2 100644
--- a/blog/_content/errors-are-values.article
+++ b/go.dev/_content/blog/errors-are-values.md
@@ -1,10 +1,11 @@
-# Errors are values
-12 Jan 2015
-Summary: Idioms and patterns for handling errors in Go.
+---
+title: Errors are values
+date: 2015-01-12
+by:
+- Rob Pike
+summary: Idioms and patterns for handling errors in Go.
+---
 
-Rob Pike
-
-##
 
 A common point of discussion among Go programmers,
 especially those new to the language, is how to handle errors.
diff --git a/blog/_content/examples.article b/go.dev/_content/blog/examples.md
similarity index 95%
rename from blog/_content/examples.article
rename to go.dev/_content/blog/examples.md
index 86d727d..b5836d2 100644
--- a/blog/_content/examples.article
+++ b/go.dev/_content/blog/examples.md
@@ -1,9 +1,13 @@
-# Testable Examples in Go
-7 May 2015
-Tags: godoc, testing
-Summary: How to add examples, which double as tests, to your packages.
-
-Andrew Gerrand
+---
+title: Testable Examples in Go
+date: 2015-05-07
+by:
+- Andrew Gerrand
+tags:
+- godoc
+- testing
+summary: How to add examples, which double as tests, to your packages.
+---
 
 ## Introduction
 
@@ -53,7 +57,7 @@
 
 Godoc will present this example alongside the `Reverse` function's documentation:
 
-.image examples/reverse.png
+{{image "examples/reverse.png"}}
 
 Running the package's test suite, we can see the example function is executed
 with no further arrangement from us:
@@ -148,6 +152,7 @@
 
 Here is a whole file example from the `sort` package:
 
+{{raw `
 	package sort_test
 
 	import (
@@ -188,6 +193,7 @@
 		// [Bob: 31 John: 42 Michael: 17 Jenny: 26]
 		// [Michael: 17 Jenny: 26 Bob: 31 John: 42]
 	}
+`}}
 
 A package can contain multiple whole file examples; one example per file.
 Take a look at the [`sort` package's source code](https://golang.org/src/sort/)
diff --git a/blog/_content/examples/reverse.png b/go.dev/_content/blog/examples/reverse.png
similarity index 100%
rename from blog/_content/examples/reverse.png
rename to go.dev/_content/blog/examples/reverse.png
Binary files differ
diff --git a/blog/_content/experiment.article b/go.dev/_content/blog/experiment.md
similarity index 97%
rename from blog/_content/experiment.article
rename to go.dev/_content/blog/experiment.md
index cf2ee69..54d5f6a 100644
--- a/blog/_content/experiment.article
+++ b/go.dev/_content/blog/experiment.md
@@ -1,15 +1,20 @@
-# Experiment, Simplify, Ship
-1 Aug 2019
-Tags: community, go2, proposals
-Summary: How we develop Go, a talk from GopherCon 2019.
-
-Russ Cox
+---
+title: Experiment, Simplify, Ship
+date: 2019-08-01
+by:
+- Russ Cox
+tags:
+- community
+- go2
+- proposals
+summary: How we develop Go, a talk from GopherCon 2019.
+---
 
 ## Introduction
 
 This is the blog post version of my talk last week at GopherCon 2019.
 
-.iframe //www.youtube.com/embed/kNHo788oO5Y?rel=0 309 549
+{{video "https://www.youtube.com/embed/kNHo788oO5Y?rel=0"}}
 
 We are all on the path to Go 2, together,
 but none of us know exactly where that path leads
@@ -19,7 +24,7 @@
 Here’s what the process looks like.
 
 <div style="margin-left: 2em;">
-.image experiment/expsimp1.png _ 179
+{{image "experiment/expsimp1.png" 179}}
 </div>
 
 We experiment with Go as it exists now,
@@ -136,8 +141,10 @@
 An example of this is when we removed
 the boolean forms of non-blocking channel operations from the language:
 
+{{raw `
 	ok := c <- x  // before Go 1, was non-blocking send
 	x, ok := <-c  // before Go 1, was non-blocking receive
+`}}
 
 These operations were also possible to do using `select`,
 making it confusing to need to decide which form to use.
@@ -178,7 +185,7 @@
 and the process cycles on and on.
 
 <div style="margin-left: 2em;">
-.image experiment/expsimp2.png _ 326
+{{image "experiment/expsimp2.png" 326}}
 </div>
 
 We shipped Go to all of you for the first time
@@ -651,6 +658,7 @@
 Here is some code from
 [`compress/lzw/writer.go`](https://go.googlesource.com/go/+/go1.12/src/compress/lzw/writer.go#209) in the standard library:
 
+{{raw `
 	// Write the savedCode if valid.
 	if e.savedCode != invalidCode {
 		if err := e.write(e, e.savedCode); err != nil {
@@ -666,6 +674,7 @@
 	if err := e.write(e, eof); err != nil {
 		return err
 	}
+`}}
 
 At a glance, this code is about half error checks.
 My eyes glaze over when I read it.
@@ -683,6 +692,7 @@
 Otherwise the `check` evaluates to the other results
 from the call. We can use `check` to simplify the lzw code:
 
+{{raw `
 	// Write the savedCode if valid.
 	if e.savedCode != invalidCode {
 		check e.write(e, e.savedCode)
@@ -694,6 +704,7 @@
 	// Write the eof code.
 	eof := uint32(1)<<e.litWidth + 1
 	check e.write(e, eof)
+`}}
 
 This version of the same code uses `check`,
 which removes four lines of code and
@@ -706,6 +717,7 @@
 That would let you write shared context-adding code just once,
 like in this snippet:
 
+{{raw `
 	handle err {
 		err = fmt.Errorf("closing writer: %w", err)
 	}
@@ -721,6 +733,7 @@
 	// Write the eof code.
 	eof := uint32(1)<<e.litWidth + 1
 	check e.write(e, eof)
+`}}
 
 In essence, `check` was a short way to write the `if` statement,
 and `handle` was like
@@ -743,6 +756,7 @@
 
 Now the same code would look like this:
 
+{{raw `
 	defer errd.Wrapf(&err, "closing writer")
 
 	// Write the savedCode if valid.
@@ -756,6 +770,7 @@
 	// Write the eof code.
 	eof := uint32(1)<<e.litWidth + 1
 	try(e.write(e, eof))
+`}}
 
 We spent most of June discussing this proposal publicly on GitHub.
 
@@ -792,6 +807,7 @@
 or any kind of map.
 For example, here is a generic channel filter:
 
+{{raw `
 	// Filter copies values from c to the returned channel,
 	// passing along only those values satisfying f.
 	func Filter(type value)(f func(value) bool, c <-chan value) <-chan value {
@@ -806,6 +822,7 @@
 		}()
 		return out
 	}
+`}}
 
 We’ve been thinking about generics since work on Go began,
 and we wrote and rejected our first concrete design in 2010.
@@ -1031,7 +1048,7 @@
 so you use version 2 of a popular Go YAML package:
 
 <div style="margin-left: 2em;">
-.image experiment/yamldeps1.png _ 214
+{{image "experiment/yamldeps1.png" 214}}
 </div>
 
 Now suppose your program
@@ -1040,7 +1057,7 @@
 and it uses version 1 of the same popular package:
 
 <div style="margin-left: 2em;">
-.image experiment/yamldeps2.png _ 557
+{{image "experiment/yamldeps2.png" 557}}
 </div>
 
 Version 1 and version 2 have incompatible APIs,
@@ -1060,7 +1077,7 @@
 that you could build before:
 
 <div style="margin-left: 2em;">
-.image experiment/yamldeps3.png _ 450
+{{image "experiment/yamldeps3.png" 450}}
 </div>
 
 It took us a while to understand this problem,
@@ -1283,7 +1300,7 @@
 ## Coda
 
 <div style="margin-left: 2em;">
-.image experiment/expsimp2.png _ 326
+{{image "experiment/expsimp2.png" 326}}
 </div>
 
 So there’s the path to Go 2.
diff --git a/blog/_content/experiment/expsimp1.graffle b/go.dev/_content/blog/experiment/expsimp1.graffle
similarity index 100%
rename from blog/_content/experiment/expsimp1.graffle
rename to go.dev/_content/blog/experiment/expsimp1.graffle
Binary files differ
diff --git a/blog/_content/experiment/expsimp1.png b/go.dev/_content/blog/experiment/expsimp1.png
similarity index 100%
rename from blog/_content/experiment/expsimp1.png
rename to go.dev/_content/blog/experiment/expsimp1.png
Binary files differ
diff --git a/blog/_content/experiment/expsimp2.graffle b/go.dev/_content/blog/experiment/expsimp2.graffle
similarity index 100%
rename from blog/_content/experiment/expsimp2.graffle
rename to go.dev/_content/blog/experiment/expsimp2.graffle
Binary files differ
diff --git a/blog/_content/experiment/expsimp2.png b/go.dev/_content/blog/experiment/expsimp2.png
similarity index 100%
rename from blog/_content/experiment/expsimp2.png
rename to go.dev/_content/blog/experiment/expsimp2.png
Binary files differ
diff --git a/blog/_content/experiment/yamldeps1.graffle b/go.dev/_content/blog/experiment/yamldeps1.graffle
similarity index 100%
rename from blog/_content/experiment/yamldeps1.graffle
rename to go.dev/_content/blog/experiment/yamldeps1.graffle
Binary files differ
diff --git a/blog/_content/experiment/yamldeps1.png b/go.dev/_content/blog/experiment/yamldeps1.png
similarity index 100%
rename from blog/_content/experiment/yamldeps1.png
rename to go.dev/_content/blog/experiment/yamldeps1.png
Binary files differ
diff --git a/blog/_content/experiment/yamldeps2.graffle b/go.dev/_content/blog/experiment/yamldeps2.graffle
similarity index 100%
rename from blog/_content/experiment/yamldeps2.graffle
rename to go.dev/_content/blog/experiment/yamldeps2.graffle
Binary files differ
diff --git a/blog/_content/experiment/yamldeps2.png b/go.dev/_content/blog/experiment/yamldeps2.png
similarity index 100%
rename from blog/_content/experiment/yamldeps2.png
rename to go.dev/_content/blog/experiment/yamldeps2.png
Binary files differ
diff --git a/blog/_content/experiment/yamldeps3.graffle b/go.dev/_content/blog/experiment/yamldeps3.graffle
similarity index 100%
rename from blog/_content/experiment/yamldeps3.graffle
rename to go.dev/_content/blog/experiment/yamldeps3.graffle
Binary files differ
diff --git a/blog/_content/experiment/yamldeps3.png b/go.dev/_content/blog/experiment/yamldeps3.png
similarity index 100%
rename from blog/_content/experiment/yamldeps3.png
rename to go.dev/_content/blog/experiment/yamldeps3.png
Binary files differ
diff --git a/blog/_content/external-libraries.article b/go.dev/_content/blog/external-libraries.md
similarity index 93%
rename from blog/_content/external-libraries.article
rename to go.dev/_content/blog/external-libraries.md
index fc21c8e..ba02d35 100644
--- a/blog/_content/external-libraries.article
+++ b/go.dev/_content/blog/external-libraries.md
@@ -1,12 +1,14 @@
-# Spotlight on external Go libraries
-3 Jun 2011
-Tags: community, libraries
-Summary: Some popular Go libraries and how to use them.
-OldURL: /spotlight-on-external-go-libraries
+---
+title: Spotlight on external Go libraries
+date: 2011-06-03
+by:
+- Andrew Gerrand
+tags:
+- community
+- libraries
+summary: Some popular Go libraries and how to use them.
+---
 
-Andrew Gerrand
-
-##
 
 While the Go authors have been working hard at improving Go's standard library,
 the greater community has created a growing ecosystem of external libraries.
diff --git a/go.dev/_content/blog/first-class-functions-in-go-and-new-go.md b/go.dev/_content/blog/first-class-functions-in-go-and-new-go.md
new file mode 100644
index 0000000..8cee67f
--- /dev/null
+++ b/go.dev/_content/blog/first-class-functions-in-go-and-new-go.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/functions-codewalk
+---
diff --git a/blog/_content/first-go-program.article b/go.dev/_content/blog/first-go-program.md
similarity index 92%
rename from blog/_content/first-go-program.article
rename to go.dev/_content/blog/first-go-program.md
index 2e25b14..18b1cb4 100644
--- a/blog/_content/first-go-program.article
+++ b/go.dev/_content/blog/first-go-program.md
@@ -1,11 +1,13 @@
-# The first Go program
-18 Jul 2013
-Tags: history
-Summary: Rob Pike dug up the first Go program ever written.
+---
+title: The first Go program
+date: 2013-07-18
+by:
+- Andrew Gerrand
+tags:
+- history
+summary: Rob Pike dug up the first Go program ever written.
+---
 
-Andrew Gerrand
-
-##
 
 Brad Fitzpatrick and I (Andrew Gerrand) recently started restructuring
 [godoc](https://golang.org/cmd/godoc/), and it occurred to me that it is one
@@ -45,7 +47,7 @@
 (The `icounter` line in the program output is the number of executed
 statements, printed for debugging.)
 
-.code first-go-program/slist.go
+{{code "first-go-program/slist.go"}}
 
 The program parses and prints an
 [S-expression](https://en.wikipedia.org/wiki/S-expression).
@@ -64,27 +66,33 @@
 considered essential since day 1 but not yet designed.
 
 A `func` was a `function`, and its signature specified return values
-_before_ arguments, separating them with `<-`, which we now use as the channel
+_before_ arguments, separating them with {{raw "`<-`"}}, which we now use as the channel
 send/receive operator. For example, the `WhiteSpace` function takes the integer
 `c` and returns a boolean.
 
+{{raw `
 	function WhiteSpace(bool <- c int)
+`}}
 
 This arrow was a stop-gap measure until a better syntax arose for declaring
 multiple return values.
 
 Methods were distinct from functions and had their own keyword.
 
+{{raw `
 	method (this *Slist) Car(*Slist <-) {
 		return this.list.car;
 	}
+`}}
 
 And methods were pre-declared in the struct definition, although that changed soon.
 
+{{raw `
 	type Slist struct {
 		...
 		Car method(*Slist <-);
 	}
+`}}
 
 There were no strings, although they were in the spec.
 To work around this, Rob had to build the input string as an `uint8` array with
diff --git a/blog/_content/first-go-program/slist.go b/go.dev/_content/blog/first-go-program/slist.go
similarity index 100%
rename from blog/_content/first-go-program/slist.go
rename to go.dev/_content/blog/first-go-program/slist.go
diff --git a/blog/_content/fosdem14.article b/go.dev/_content/blog/fosdem14.md
similarity index 88%
rename from blog/_content/fosdem14.article
rename to go.dev/_content/blog/fosdem14.md
index 22daed7..e6d72bc 100644
--- a/blog/_content/fosdem14.article
+++ b/go.dev/_content/blog/fosdem14.md
@@ -1,9 +1,14 @@
-# Go talks at FOSDEM 2014
-24 Feb 2014
-Tags: fosdem, youtube, talk
-Summary: Reporting from the Go Devroom at FOSDEM 2014.
-
-Andrew Gerrand
+---
+title: Go talks at FOSDEM 2014
+date: 2014-02-24
+by:
+- Andrew Gerrand
+tags:
+- fosdem
+- youtube
+- talk
+summary: Reporting from the Go Devroom at FOSDEM 2014.
+---
 
 ## Introduction
 
@@ -33,7 +38,7 @@
 paid off.
 Sugu also talks abou tips and techniques used to scale Vitess using Go.
 
-.iframe //www.youtube.com/embed/qATTTSg6zXk 310 550
+{{video "https://www.youtube.com/embed/qATTTSg6zXk"}}
 
 The slides for the talk are [available here](https://github.com/youtube/vitess/blob/master/doc/Vitess2014.pdf?raw=true).
 
@@ -45,7 +50,7 @@
 this talk, Brad Fitzpatrick and Mathieu Lonjaret explain why they built it,
 what it does, and talk about its design.
 
-.iframe //www.youtube.com/embed/yvjeIZgykiA 310 550
+{{video "https://www.youtube.com/embed/yvjeIZgykiA"}}
 
 ## Write your own Go compiler
 
@@ -60,7 +65,7 @@
 will be inspired to contribute to one of them or even to write a new one of
 your own."
 
-.iframe //www.youtube.com/embed/Qe8Dq7V3hXY 310 550
+{{video "https://www.youtube.com/embed/Qe8Dq7V3hXY"}}
 
 ## More
 
diff --git a/go.dev/_content/blog/from-zero-to-go-launching-on-google.md b/go.dev/_content/blog/from-zero-to-go-launching-on-google.md
new file mode 100644
index 0000000..1ce25d8
--- /dev/null
+++ b/go.dev/_content/blog/from-zero-to-go-launching-on-google.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/turkey-doodle
+---
diff --git a/blog/_content/functions-codewalk.article b/go.dev/_content/blog/functions-codewalk.md
similarity index 70%
rename from blog/_content/functions-codewalk.article
rename to go.dev/_content/blog/functions-codewalk.md
index 1ae0b84..22a6fca 100644
--- a/blog/_content/functions-codewalk.article
+++ b/go.dev/_content/blog/functions-codewalk.md
@@ -1,12 +1,15 @@
-# First Class Functions in Go
-30 Jun 2011
-Tags: codewalk, function, technical
-Summary: Announcing a new Go codewalk, exploring first class functions.
-OldURL: /first-class-functions-in-go-and-new-go
+---
+title: First Class Functions in Go
+date: 2011-06-30
+by:
+- Andrew Gerrand
+tags:
+- codewalk
+- function
+- technical
+summary: Announcing a new Go codewalk, exploring first class functions.
+---
 
-Andrew Gerrand
-
-##
 
 Programmers new to Go are often surprised by its support for function types,
 functions as values, and closures.
diff --git a/blog/_content/fuzz-beta.article b/go.dev/_content/blog/fuzz-beta.md
similarity index 94%
rename from blog/_content/fuzz-beta.article
rename to go.dev/_content/blog/fuzz-beta.md
index dca52c6..97ed134 100644
--- a/blog/_content/fuzz-beta.article
+++ b/go.dev/_content/blog/fuzz-beta.md
@@ -1,13 +1,15 @@
-# Fuzzing is Beta Ready
-03 Jun 2021
-Tags: fuzz, testing
-Summary:  Native Go fuzzing is now ready for beta testing in the dev.fuzz development branch.
+---
+title: Fuzzing is Beta Ready
+date: 2021-06-03
+by:
+- Katie Hockman
+- Jay Conrod
+tags:
+- fuzz
+- testing
+summary: Native Go fuzzing is now ready for beta testing in the dev.fuzz development branch.
+---
 
-Katie Hockman
-
-Jay Conrod
-
-##
 
 We are excited to announce that native fuzzing is ready for beta testing in its
 development branch, [dev.fuzz](https://github.com/golang/go/tree/dev.fuzz)!
@@ -129,4 +131,4 @@
 in the [#fuzzing channel](https://gophers.slack.com/archives/CH5KV1AKE) in
 Gophers Slack.
 
-Happy fuzzing!
\ No newline at end of file
+Happy fuzzing!
diff --git a/blog/_content/gccgo-in-gcc-471.article b/go.dev/_content/blog/gccgo-in-gcc-471.md
similarity index 94%
rename from blog/_content/gccgo-in-gcc-471.article
rename to go.dev/_content/blog/gccgo-in-gcc-471.md
index 1e2e4f2..cb7149a 100644
--- a/blog/_content/gccgo-in-gcc-471.article
+++ b/go.dev/_content/blog/gccgo-in-gcc-471.md
@@ -1,11 +1,13 @@
-# Gccgo in GCC 4.7.1
-11 Jul 2012
-Tags: release
-Summary: GCC 4.7.1 adds support for Go 1.
+---
+title: Gccgo in GCC 4.7.1
+date: 2012-07-11
+by:
+- Ian Lance Taylor
+tags:
+- release
+summary: GCC 4.7.1 adds support for Go 1.
+---
 
-Ian Lance Taylor
-
-##
 
 The Go language has always been defined by a [spec](https://golang.org/ref/spec),
 not an implementation.
diff --git a/go.dev/_content/blog/gcdk-whats-new-in-march-2019.md b/go.dev/_content/blog/gcdk-whats-new-in-march-2019.md
new file mode 100644
index 0000000..c8aa14d
--- /dev/null
+++ b/go.dev/_content/blog/gcdk-whats-new-in-march-2019.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/go-cloud2019
+---
diff --git a/blog/_content/generate.article b/go.dev/_content/blog/generate.md
similarity index 97%
rename from blog/_content/generate.article
rename to go.dev/_content/blog/generate.md
index 87c42b0..1a657de 100644
--- a/blog/_content/generate.article
+++ b/go.dev/_content/blog/generate.md
@@ -1,11 +1,14 @@
-# Generating code
-22 Dec 2014
-Tags: programming, technical
-Summary: How to use go generate.
+---
+title: Generating code
+date: 2014-12-22
+by:
+- Rob Pike
+tags:
+- programming
+- technical
+summary: How to use go generate.
+---
 
-Rob Pike
-
-##
 
 A property of universal computation—Turing completeness—is that a computer program can write a computer program.
 This is a powerful idea that is not appreciated as often as it might be, even though it happens frequently.
@@ -149,6 +152,7 @@
 
 Let's run it:
 
+{{raw `
 	$ go generate
 	$ cat pill_string.go
 	// Code generated by stringer -type Pill pill.go; DO NOT EDIT.
@@ -168,6 +172,7 @@
 		return _Pill_name[_Pill_index[i]:_Pill_index[i+1]]
 	}
 	$
+`}}
 
 Every time we change the definition of `Pill` or the constants, all we need to do is run
 
diff --git a/blog/_content/generics-next-step.article b/go.dev/_content/blog/generics-next-step.md
similarity index 95%
rename from blog/_content/generics-next-step.article
rename to go.dev/_content/blog/generics-next-step.md
index 72014d3..7c463db 100644
--- a/blog/_content/generics-next-step.article
+++ b/go.dev/_content/blog/generics-next-step.md
@@ -1,11 +1,15 @@
-# The Next Step for Generics
-16 Jun 2020
-Tags: go2, proposals, generics
-Summary: An updated generics design draft, and a translation tool for experimentation
-
-Ian Lance Taylor
-
-Robert Griesemer
+---
+title: The Next Step for Generics
+date: 2020-06-16
+by:
+- Ian Lance Taylor
+- Robert Griesemer
+tags:
+- go2
+- proposals
+- generics
+summary: An updated generics design draft, and a translation tool for experimentation
+---
 
 ## Introduction
 
diff --git a/blog/_content/generics-proposal.article b/go.dev/_content/blog/generics-proposal.md
similarity index 93%
rename from blog/_content/generics-proposal.article
rename to go.dev/_content/blog/generics-proposal.md
index 0f83878..14e32b4 100644
--- a/blog/_content/generics-proposal.article
+++ b/go.dev/_content/blog/generics-proposal.md
@@ -1,9 +1,14 @@
-# A Proposal for Adding Generics to Go
-12 Jan 2021
-Tags: go2, proposals, generics
-Summary: Generics is entering the language change proposal process
-
-Ian Lance Taylor
+---
+title: A Proposal for Adding Generics to Go
+date: 2021-01-12
+by:
+- Ian Lance Taylor
+tags:
+- go2
+- proposals
+- generics
+summary: Generics is entering the language change proposal process
+---
 
 ## Generics proposal
 
diff --git a/go.dev/_content/blog/getthee-to-go-meetup.md b/go.dev/_content/blog/getthee-to-go-meetup.md
new file mode 100644
index 0000000..69217aa
--- /dev/null
+++ b/go.dev/_content/blog/getthee-to-go-meetup.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/meetups
+---
diff --git a/go.dev/_content/blog/getting-to-know-go-community.md b/go.dev/_content/blog/getting-to-know-go-community.md
new file mode 100644
index 0000000..7cdaeb5
--- /dev/null
+++ b/go.dev/_content/blog/getting-to-know-go-community.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/survey2011
+---
diff --git a/go.dev/_content/blog/gif-decoder-exercise-in-go-interfaces.md b/go.dev/_content/blog/gif-decoder-exercise-in-go-interfaces.md
new file mode 100644
index 0000000..84d1a0e
--- /dev/null
+++ b/go.dev/_content/blog/gif-decoder-exercise-in-go-interfaces.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/gif-decoder
+---
diff --git a/blog/_content/gif-decoder.article b/go.dev/_content/blog/gif-decoder.md
similarity index 94%
rename from blog/_content/gif-decoder.article
rename to go.dev/_content/blog/gif-decoder.md
index d848210..8d02802 100644
--- a/blog/_content/gif-decoder.article
+++ b/go.dev/_content/blog/gif-decoder.md
@@ -1,10 +1,20 @@
-# A GIF decoder: an exercise in Go interfaces
-25 May 2011
-Tags: gif, gopher, image, interface, lagomorph, lzw, moustache, rodent, technical
-Summary: How Go's interfaces work nicely in the Go GIF decoder.
-OldURL: /gif-decoder-exercise-in-go-interfaces
-
-Rob Pike
+---
+title: "A GIF decoder: an exercise in Go interfaces"
+date: 2011-05-25
+by:
+- Rob Pike
+tags:
+- gif
+- gopher
+- image
+- interface
+- lagomorph
+- lzw
+- moustache
+- rodent
+- technical
+summary: How Go's interfaces work nicely in the Go GIF decoder.
+---
 
 ## Introduction
 
@@ -17,11 +27,11 @@
 In that vein, we demonstrated a program called [Moustachio](http://moustach-io.appspot.com/)
 that makes it easy to improve a picture such as this one:
 
-.image gif-decoder/image00.jpg
+{{image "gif-decoder/image00.jpg"}}
 
 by adding a moustache and sharing the result:
 
-.image gif-decoder/image02.jpg
+{{image "gif-decoder/image02.jpg"}}
 
 All the graphical processing, including rendering the antialiased moustache,
 is done by a Go program running on App Engine.
@@ -61,7 +71,7 @@
 The compressed data is then broken into length-delimited blocks with a one-byte
 count (0-255) followed by that many bytes:
 
-.image gif-decoder/image03.gif
+{{image "gif-decoder/image03.gif"}}
 
 ## Deblocking the pixel data
 
@@ -209,6 +219,6 @@
 
 That deserves another picture, a GIF this time:
 
-.image gif-decoder/image01.gif
+{{image "gif-decoder/image01.gif"}}
 
 The GIF format is defined at [http://www.w3.org/Graphics/GIF/spec-gif89a.txt](http://www.w3.org/Graphics/GIF/spec-gif89a.txt).
diff --git a/blog/_content/gif-decoder/image00.jpg b/go.dev/_content/blog/gif-decoder/image00.jpg
similarity index 100%
rename from blog/_content/gif-decoder/image00.jpg
rename to go.dev/_content/blog/gif-decoder/image00.jpg
Binary files differ
diff --git a/blog/_content/gif-decoder/image01.gif b/go.dev/_content/blog/gif-decoder/image01.gif
similarity index 100%
rename from blog/_content/gif-decoder/image01.gif
rename to go.dev/_content/blog/gif-decoder/image01.gif
Binary files differ
diff --git a/blog/_content/gif-decoder/image02.jpg b/go.dev/_content/blog/gif-decoder/image02.jpg
similarity index 100%
rename from blog/_content/gif-decoder/image02.jpg
rename to go.dev/_content/blog/gif-decoder/image02.jpg
Binary files differ
diff --git a/blog/_content/gif-decoder/image03.gif b/go.dev/_content/blog/gif-decoder/image03.gif
similarity index 100%
rename from blog/_content/gif-decoder/image03.gif
rename to go.dev/_content/blog/gif-decoder/image03.gif
Binary files differ
diff --git a/go.dev/_content/blog/go-11-is-released.md b/go.dev/_content/blog/go-11-is-released.md
new file mode 100644
index 0000000..47ba4a5
--- /dev/null
+++ b/go.dev/_content/blog/go-11-is-released.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/go1.1
+---
diff --git a/go.dev/_content/blog/go-and-google-app-engine.md b/go.dev/_content/blog/go-and-google-app-engine.md
new file mode 100644
index 0000000..5e5433f
--- /dev/null
+++ b/go.dev/_content/blog/go-and-google-app-engine.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/appengine
+---
diff --git a/go.dev/_content/blog/go-and-google-cloud-platform.md b/go.dev/_content/blog/go-and-google-cloud-platform.md
new file mode 100644
index 0000000..c1f5d26
--- /dev/null
+++ b/go.dev/_content/blog/go-and-google-cloud-platform.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/io2013-talks-cloud
+---
diff --git a/go.dev/_content/blog/go-app-engine-sdk-155-released.md b/go.dev/_content/blog/go-app-engine-sdk-155-released.md
new file mode 100644
index 0000000..b094f6a
--- /dev/null
+++ b/go.dev/_content/blog/go-app-engine-sdk-155-released.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/appengine-155
+---
diff --git a/go.dev/_content/blog/go-at-google-io-2011-videos.md b/go.dev/_content/blog/go-at-google-io-2011-videos.md
new file mode 100644
index 0000000..ef71e6f
--- /dev/null
+++ b/go.dev/_content/blog/go-at-google-io-2011-videos.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/io2011
+---
diff --git a/go.dev/_content/blog/go-at-heroku.md b/go.dev/_content/blog/go-at-heroku.md
new file mode 100644
index 0000000..54c3df8
--- /dev/null
+++ b/go.dev/_content/blog/go-at-heroku.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/heroku
+---
diff --git a/go.dev/_content/blog/go-at-io-frequently-asked-questions.md b/go.dev/_content/blog/go-at-io-frequently-asked-questions.md
new file mode 100644
index 0000000..ec9f87f
--- /dev/null
+++ b/go.dev/_content/blog/go-at-io-frequently-asked-questions.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/io2010-faq
+---
diff --git a/go.dev/_content/blog/go-becomes-more-stable.md b/go.dev/_content/blog/go-becomes-more-stable.md
new file mode 100644
index 0000000..25fade0
--- /dev/null
+++ b/go.dev/_content/blog/go-becomes-more-stable.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/stable-releases
+---
diff --git a/blog/_content/go-brand.article b/go.dev/_content/blog/go-brand.md
similarity index 89%
rename from blog/_content/go-brand.article
rename to go.dev/_content/blog/go-brand.md
index db2f3b6..d18bb8d 100644
--- a/blog/_content/go-brand.article
+++ b/go.dev/_content/blog/go-brand.md
@@ -1,9 +1,12 @@
-# Go's New Brand
-26 Apr 2018
-Tags: brand
-Summary: Go’s new look and logo (don't worry, the mascot isn’t changing!).
-
-Steve Francia
+---
+title: Go's New Brand
+date: 2018-04-26
+by:
+- Steve Francia
+tags:
+- brand
+summary: Go’s new look and logo (don't worry, the mascot isn’t changing!).
+---
 
 ## Introduction
 
@@ -28,13 +31,13 @@
 Go gopher, creating a familiar shape and allowing the mark and the mascot to
 pair well together.
 
-.image go-brand/logos.jpg
+{{image "go-brand/logos.jpg"}}
 
 Our new logo went through an extensive design process. Here are some of the
 revisions we went through…
 
 <div><center>
-.iframe //www.youtube.com/embed/V4t-ymImW6c 315 560
+{{video "https://www.youtube.com/embed/V4t-ymImW6c"}}
 </center></div>
 
 ## New Brand Guide
@@ -45,9 +48,9 @@
 book”. It is a single document that serves as a guide and reference to
 designers, writers, and developers to create consistent, on-brand content.
 
-.image go-brand/Go-BB_cover.jpg
-.image go-brand/Go-BB_spread1.jpg
-.image go-brand/Go-BB_spread2.jpg
+{{image "go-brand/Go-BB_cover.jpg"}}
+{{image "go-brand/Go-BB_spread1.jpg"}}
+{{image "go-brand/Go-BB_spread2.jpg"}}
 
 ## New presentation themes
 
@@ -56,7 +59,7 @@
 person at meetups and conferences as well as online. Go community members are
 welcome to use this theme for their own presentations.
 
-.image go-brand/go-slides-4up.jpg
+{{image "go-brand/go-slides-4up.jpg"}}
 
 The presentations are available as Google Slides presentations. We chose Google
 slides as it is easy to share and maintain updates. People are welcome to port
diff --git a/blog/_content/go-brand/Go-BB_cover.jpg b/go.dev/_content/blog/go-brand/Go-BB_cover.jpg
similarity index 100%
rename from blog/_content/go-brand/Go-BB_cover.jpg
rename to go.dev/_content/blog/go-brand/Go-BB_cover.jpg
Binary files differ
diff --git a/blog/_content/go-brand/Go-BB_spread1.jpg b/go.dev/_content/blog/go-brand/Go-BB_spread1.jpg
similarity index 100%
rename from blog/_content/go-brand/Go-BB_spread1.jpg
rename to go.dev/_content/blog/go-brand/Go-BB_spread1.jpg
Binary files differ
diff --git a/blog/_content/go-brand/Go-BB_spread2.jpg b/go.dev/_content/blog/go-brand/Go-BB_spread2.jpg
similarity index 100%
rename from blog/_content/go-brand/Go-BB_spread2.jpg
rename to go.dev/_content/blog/go-brand/Go-BB_spread2.jpg
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/EPS/Go-Logo_Versions.eps b/go.dev/_content/blog/go-brand/Go-Logo/EPS/Go-Logo_Versions.eps
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/EPS/Go-Logo_Versions.eps
rename to go.dev/_content/blog/go-brand/Go-Logo/EPS/Go-Logo_Versions.eps
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/Go-Logo_Versions.ai b/go.dev/_content/blog/go-brand/Go-Logo/Go-Logo_Versions.ai
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/Go-Logo_Versions.ai
rename to go.dev/_content/blog/go-brand/Go-Logo/Go-Logo_Versions.ai
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/Go-Logo_Versions.pdf b/go.dev/_content/blog/go-brand/Go-Logo/Go-Logo_Versions.pdf
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/Go-Logo_Versions.pdf
rename to go.dev/_content/blog/go-brand/Go-Logo/Go-Logo_Versions.pdf
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/JPG/Go-Logo_Aqua.jpg b/go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_Aqua.jpg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/JPG/Go-Logo_Aqua.jpg
rename to go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_Aqua.jpg
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/JPG/Go-Logo_Black.jpg b/go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_Black.jpg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/JPG/Go-Logo_Black.jpg
rename to go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_Black.jpg
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/JPG/Go-Logo_Blue.jpg b/go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_Blue.jpg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/JPG/Go-Logo_Blue.jpg
rename to go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_Blue.jpg
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/JPG/Go-Logo_Fuchsia.jpg b/go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_Fuchsia.jpg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/JPG/Go-Logo_Fuchsia.jpg
rename to go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_Fuchsia.jpg
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/JPG/Go-Logo_LightBlue.jpg b/go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_LightBlue.jpg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/JPG/Go-Logo_LightBlue.jpg
rename to go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_LightBlue.jpg
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/JPG/Go-Logo_Yellow.jpg b/go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_Yellow.jpg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/JPG/Go-Logo_Yellow.jpg
rename to go.dev/_content/blog/go-brand/Go-Logo/JPG/Go-Logo_Yellow.jpg
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/PNG/Go-Logo_Aqua.png b/go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_Aqua.png
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/PNG/Go-Logo_Aqua.png
rename to go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_Aqua.png
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/PNG/Go-Logo_Black.png b/go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_Black.png
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/PNG/Go-Logo_Black.png
rename to go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_Black.png
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/PNG/Go-Logo_Blue.png b/go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_Blue.png
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/PNG/Go-Logo_Blue.png
rename to go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_Blue.png
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/PNG/Go-Logo_Fuchsia.png b/go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_Fuchsia.png
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/PNG/Go-Logo_Fuchsia.png
rename to go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_Fuchsia.png
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/PNG/Go-Logo_LightBlue.png b/go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_LightBlue.png
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/PNG/Go-Logo_LightBlue.png
rename to go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_LightBlue.png
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/PNG/Go-Logo_White.png b/go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_White.png
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/PNG/Go-Logo_White.png
rename to go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_White.png
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/PNG/Go-Logo_Yellow.png b/go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_Yellow.png
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/PNG/Go-Logo_Yellow.png
rename to go.dev/_content/blog/go-brand/Go-Logo/PNG/Go-Logo_Yellow.png
Binary files differ
diff --git a/blog/_content/go-brand/Go-Logo/SVG/Go-Logo_Aqua.svg b/go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_Aqua.svg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/SVG/Go-Logo_Aqua.svg
rename to go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_Aqua.svg
diff --git a/blog/_content/go-brand/Go-Logo/SVG/Go-Logo_Black.svg b/go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_Black.svg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/SVG/Go-Logo_Black.svg
rename to go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_Black.svg
diff --git a/blog/_content/go-brand/Go-Logo/SVG/Go-Logo_Blue.svg b/go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_Blue.svg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/SVG/Go-Logo_Blue.svg
rename to go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_Blue.svg
diff --git a/blog/_content/go-brand/Go-Logo/SVG/Go-Logo_Fuchsia.svg b/go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_Fuchsia.svg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/SVG/Go-Logo_Fuchsia.svg
rename to go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_Fuchsia.svg
diff --git a/blog/_content/go-brand/Go-Logo/SVG/Go-Logo_LightBlue.svg b/go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_LightBlue.svg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/SVG/Go-Logo_LightBlue.svg
rename to go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_LightBlue.svg
diff --git a/blog/_content/go-brand/Go-Logo/SVG/Go-Logo_White.svg b/go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_White.svg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/SVG/Go-Logo_White.svg
rename to go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_White.svg
diff --git a/blog/_content/go-brand/Go-Logo/SVG/Go-Logo_Yellow.svg b/go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_Yellow.svg
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/SVG/Go-Logo_Yellow.svg
rename to go.dev/_content/blog/go-brand/Go-Logo/SVG/Go-Logo_Yellow.svg
diff --git a/blog/_content/go-brand/Go-Logo/copyright.txt b/go.dev/_content/blog/go-brand/Go-Logo/copyright.txt
similarity index 100%
rename from blog/_content/go-brand/Go-Logo/copyright.txt
rename to go.dev/_content/blog/go-brand/Go-Logo/copyright.txt
diff --git a/blog/_content/go-brand/Go-brand-book-v1.0.pdf b/go.dev/_content/blog/go-brand/Go-brand-book-v1.0.pdf
similarity index 100%
rename from blog/_content/go-brand/Go-brand-book-v1.0.pdf
rename to go.dev/_content/blog/go-brand/Go-brand-book-v1.0.pdf
Binary files differ
diff --git a/blog/_content/go-brand/go-logos-1.0.zip b/go.dev/_content/blog/go-brand/go-logos-1.0.zip
similarity index 100%
rename from blog/_content/go-brand/go-logos-1.0.zip
rename to go.dev/_content/blog/go-brand/go-logos-1.0.zip
Binary files differ
diff --git a/blog/_content/go-brand/go-slides-4up.jpg b/go.dev/_content/blog/go-brand/go-slides-4up.jpg
similarity index 100%
rename from blog/_content/go-brand/go-slides-4up.jpg
rename to go.dev/_content/blog/go-brand/go-slides-4up.jpg
Binary files differ
diff --git a/blog/_content/go-brand/logos.jpg b/go.dev/_content/blog/go-brand/logos.jpg
similarity index 100%
rename from blog/_content/go-brand/logos.jpg
rename to go.dev/_content/blog/go-brand/logos.jpg
Binary files differ
diff --git a/blog/_content/go-cloud.article b/go.dev/_content/blog/go-cloud.md
similarity index 96%
rename from blog/_content/go-cloud.article
rename to go.dev/_content/blog/go-cloud.md
index ff10fbf..fe7acbb 100644
--- a/blog/_content/go-cloud.article
+++ b/go.dev/_content/blog/go-cloud.md
@@ -1,10 +1,11 @@
-# Portable Cloud Programming with Go Cloud
-24 Jul 2018
-Summary: Announcing Go Cloud, for portable cloud programming with Go.
-
-Eno Compton
-
-Cassandra Salisbury
+---
+title: Portable Cloud Programming with Go Cloud
+date: 2018-07-24
+by:
+- Eno Compton
+- Cassandra Salisbury
+summary: Announcing Go Cloud, for portable cloud programming with Go.
+---
 
 ## Introduction
 
diff --git a/blog/_content/go-cloud2019.article b/go.dev/_content/blog/go-cloud2019.md
similarity index 93%
rename from blog/_content/go-cloud2019.article
rename to go.dev/_content/blog/go-cloud2019.md
index 7c22a33..5cd2557 100644
--- a/blog/_content/go-cloud2019.article
+++ b/go.dev/_content/blog/go-cloud2019.md
@@ -1,9 +1,10 @@
-# What's new in the Go Cloud Development Kit
-4 Mar 2019
-Summary: Recent changes to the Go Cloud Development Kit (Go CDK).
-OldURL: /gcdk-whats-new-in-march-2019
-
-The Go Cloud Development Kit team at Google
+---
+title: What's new in the Go Cloud Development Kit
+date: 2019-03-04
+by:
+- The Go Cloud Development Kit team at Google
+summary: Recent changes to the Go Cloud Development Kit (Go CDK).
+---
 
 ## Introduction
 
diff --git a/go.dev/_content/blog/go-concurrency-patterns-timing-out-and.md b/go.dev/_content/blog/go-concurrency-patterns-timing-out-and.md
new file mode 100644
index 0000000..5ba0b7f
--- /dev/null
+++ b/go.dev/_content/blog/go-concurrency-patterns-timing-out-and.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/concurrency-timeouts
+---
diff --git a/blog/_content/go-developer-network.article b/go.dev/_content/blog/go-developer-network.md
similarity index 89%
rename from blog/_content/go-developer-network.article
rename to go.dev/_content/blog/go-developer-network.md
index 5e560f3..e855608 100644
--- a/blog/_content/go-developer-network.article
+++ b/go.dev/_content/blog/go-developer-network.md
@@ -1,11 +1,13 @@
-# The New Go Developer Network
-14 Mar 2019
-Tags: Community
-Summary: Announcing the Go Developer Network, a collection of Go user groups sharing best practices.
+---
+title: The New Go Developer Network
+date: 2019-03-14
+by:
+- GoBridge Leadership Team
+tags:
+- Community
+summary: Announcing the Go Developer Network, a collection of Go user groups sharing best practices.
+---
 
-GoBridge Leadership Team
-
-##
 
 A sense of community flourishes when we come together in person. As handles become names
 and avatars become faces, the smiles are real and true friendship can grow. There is joy
diff --git a/go.dev/_content/blog/go-fmt-your-code.md b/go.dev/_content/blog/go-fmt-your-code.md
new file mode 100644
index 0000000..484c1bd
--- /dev/null
+++ b/go.dev/_content/blog/go-fmt-your-code.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/gofmt
+---
diff --git a/blog/_content/go-fonts.article b/go.dev/_content/blog/go-fonts.md
similarity index 95%
rename from blog/_content/go-fonts.article
rename to go.dev/_content/blog/go-fonts.md
index 34e390b..0e9905b 100644
--- a/blog/_content/go-fonts.article
+++ b/go.dev/_content/blog/go-fonts.md
@@ -1,12 +1,12 @@
-# Go fonts
-16 Nov 2016
-Summary: Announcing the Go font family, by Bigelow & Holmes.
-
-Nigel Tao
-
-Chuck Bigelow
-
-Rob Pike
+---
+title: Go fonts
+date: 2016-11-16
+by:
+- Nigel Tao
+- Chuck Bigelow
+- Rob Pike
+summary: Announcing the Go font family, by Bigelow & Holmes.
+---
 
 ## An Announcement
 
@@ -24,7 +24,7 @@
 Go source code looks particularly good when displayed in Go fonts, as its name implies, with things like
 punctuation characters easily distinguishable and operators lined up and placed consistently:
 
-.image go-fonts/go-font-code.png _ 519
+{{image "go-fonts/go-font-code.png" 519}}
 
 Perhaps the most remarkable feature of the Go fonts is their license:
 They are licensed under the same open source license as the rest of the Go project's software,
@@ -32,11 +32,11 @@
 
 Here are samples of the proportionally-spaced...
 
-.image go-fonts/go-regular.png _ 600
+{{image "go-fonts/go-regular.png" 600}}
 
 and monospaced fonts:
 
-.image go-fonts/go-mono.png _ 600
+{{image "go-fonts/go-mono.png" 600}}
 
 ## How to use them
 
@@ -104,7 +104,7 @@
 slanted roman sans-serif italics are preferable to truly "cursive" sans
 Italics, in part because of history and design. [3]
 
-.image go-fonts/abdgpq-proportional.png
+{{image "go-fonts/abdgpq-proportional.png"}}
 
 ### The x-height
 
@@ -198,7 +198,7 @@
 sans-serif fonts, it is believed that slanted roman slab-serifs fonts may
 be more legible than truly "cursive" italics.
 
-.image go-fonts/abdgpq-mono.png
+{{image "go-fonts/abdgpq-mono.png"}}
 
 ### The x-height
 
@@ -291,8 +291,8 @@
 
 From [en.wikipedia.org/wiki/Jabberwocky](https://en.wikipedia.org/wiki/Jabberwocky):
 
-.image go-fonts/go-font-jabberwocky.png _ 500
+{{image "go-fonts/go-font-jabberwocky.png" 500}}
 
 There is no Greek version listed. Instead, a pangram from [clagnut.com/blog/2380/#Greek](http://clagnut.com/blog/2380/#Greek):
 
-.image go-fonts/go-font-greek.png _ 530
+{{image "go-fonts/go-font-greek.png" 530}}
diff --git a/blog/_content/go-fonts/abdgpq-mono.png b/go.dev/_content/blog/go-fonts/abdgpq-mono.png
similarity index 100%
rename from blog/_content/go-fonts/abdgpq-mono.png
rename to go.dev/_content/blog/go-fonts/abdgpq-mono.png
Binary files differ
diff --git a/blog/_content/go-fonts/abdgpq-proportional.png b/go.dev/_content/blog/go-fonts/abdgpq-proportional.png
similarity index 100%
rename from blog/_content/go-fonts/abdgpq-proportional.png
rename to go.dev/_content/blog/go-fonts/abdgpq-proportional.png
Binary files differ
diff --git a/blog/_content/go-fonts/go-font-code.png b/go.dev/_content/blog/go-fonts/go-font-code.png
similarity index 100%
rename from blog/_content/go-fonts/go-font-code.png
rename to go.dev/_content/blog/go-fonts/go-font-code.png
Binary files differ
diff --git a/blog/_content/go-fonts/go-font-greek.png b/go.dev/_content/blog/go-fonts/go-font-greek.png
similarity index 100%
rename from blog/_content/go-fonts/go-font-greek.png
rename to go.dev/_content/blog/go-fonts/go-font-greek.png
Binary files differ
diff --git a/blog/_content/go-fonts/go-font-jabberwocky.png b/go.dev/_content/blog/go-fonts/go-font-jabberwocky.png
similarity index 100%
rename from blog/_content/go-fonts/go-font-jabberwocky.png
rename to go.dev/_content/blog/go-fonts/go-font-jabberwocky.png
Binary files differ
diff --git a/blog/_content/go-fonts/go-mono.png b/go.dev/_content/blog/go-fonts/go-mono.png
similarity index 100%
rename from blog/_content/go-fonts/go-mono.png
rename to go.dev/_content/blog/go-fonts/go-mono.png
Binary files differ
diff --git a/blog/_content/go-fonts/go-regular.png b/go.dev/_content/blog/go-fonts/go-regular.png
similarity index 100%
rename from blog/_content/go-fonts/go-regular.png
rename to go.dev/_content/blog/go-fonts/go-regular.png
Binary files differ
diff --git a/go.dev/_content/blog/go-for-app-engine-is-now-generally.md b/go.dev/_content/blog/go-for-app-engine-is-now-generally.md
new file mode 100644
index 0000000..17486f3
--- /dev/null
+++ b/go.dev/_content/blog/go-for-app-engine-is-now-generally.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/appengine-ga
+---
diff --git a/go.dev/_content/blog/go-image-package.md b/go.dev/_content/blog/go-image-package.md
new file mode 100644
index 0000000..434fc10
--- /dev/null
+++ b/go.dev/_content/blog/go-image-package.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/image
+---
diff --git a/go.dev/_content/blog/go-imagedraw-package.md b/go.dev/_content/blog/go-imagedraw-package.md
new file mode 100644
index 0000000..b03e7ff
--- /dev/null
+++ b/go.dev/_content/blog/go-imagedraw-package.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/image-draw
+---
diff --git a/go.dev/_content/blog/go-maps-in-action.md b/go.dev/_content/blog/go-maps-in-action.md
new file mode 100644
index 0000000..58f1333
--- /dev/null
+++ b/go.dev/_content/blog/go-maps-in-action.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/maps
+---
diff --git a/go.dev/_content/blog/go-one-year-ago-today.md b/go.dev/_content/blog/go-one-year-ago-today.md
new file mode 100644
index 0000000..bd771e8
--- /dev/null
+++ b/go.dev/_content/blog/go-one-year-ago-today.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/1year
+---
diff --git a/go.dev/_content/blog/go-programming-language-turns-two.md b/go.dev/_content/blog/go-programming-language-turns-two.md
new file mode 100644
index 0000000..ba2f2fc
--- /dev/null
+++ b/go.dev/_content/blog/go-programming-language-turns-two.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/2years
+---
diff --git a/go.dev/_content/blog/go-programming-session-video-from.md b/go.dev/_content/blog/go-programming-session-video-from.md
new file mode 100644
index 0000000..ac0e2e0
--- /dev/null
+++ b/go.dev/_content/blog/go-programming-session-video-from.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/io2010
+---
diff --git a/go.dev/_content/blog/go-slices-usage-and-internals.md b/go.dev/_content/blog/go-slices-usage-and-internals.md
new file mode 100644
index 0000000..f1e1437
--- /dev/null
+++ b/go.dev/_content/blog/go-slices-usage-and-internals.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/slices-intro
+---
diff --git a/go.dev/_content/blog/go-turns-three.md b/go.dev/_content/blog/go-turns-three.md
new file mode 100644
index 0000000..d99bb33
--- /dev/null
+++ b/go.dev/_content/blog/go-turns-three.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/3years
+---
diff --git a/go.dev/_content/blog/go-updates-in-app-engine-171.md b/go.dev/_content/blog/go-updates-in-app-engine-171.md
new file mode 100644
index 0000000..fbeb8e6
--- /dev/null
+++ b/go.dev/_content/blog/go-updates-in-app-engine-171.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/appengine-171
+---
diff --git a/go.dev/_content/blog/go-videos-from-google-io-2012.md b/go.dev/_content/blog/go-videos-from-google-io-2012.md
new file mode 100644
index 0000000..ddc5a45
--- /dev/null
+++ b/go.dev/_content/blog/go-videos-from-google-io-2012.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/io2012-videos
+---
diff --git a/go.dev/_content/blog/go-whats-new-in-march-2010.md b/go.dev/_content/blog/go-whats-new-in-march-2010.md
new file mode 100644
index 0000000..585b09e
--- /dev/null
+++ b/go.dev/_content/blog/go-whats-new-in-march-2010.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/hello-world
+---
diff --git a/go.dev/_content/blog/go-wins-2010-bossie-award.md b/go.dev/_content/blog/go-wins-2010-bossie-award.md
new file mode 100644
index 0000000..61d34b2
--- /dev/null
+++ b/go.dev/_content/blog/go-wins-2010-bossie-award.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/bossie
+---
diff --git a/blog/_content/go.dev.article b/go.dev/_content/blog/go.dev.md
similarity index 84%
rename from blog/_content/go.dev.article
rename to go.dev/_content/blog/go.dev.md
index ea7dccb..3084b00 100644
--- a/blog/_content/go.dev.article
+++ b/go.dev/_content/blog/go.dev.md
@@ -1,11 +1,11 @@
-# Go.dev: a new hub for Go developers
-13 Nov 2019
-Summary: Announcing go.dev, which answers: who else is using Go, what do they use it for, and how can I find useful Go packages?
+---
+title: "Go.dev: a new hub for Go developers"
+date: 2019-11-13
+by:
+- Steve Francia and Julie Qiu
+summary: "Announcing go.dev, which answers: who else is using Go, what do they use it for, and how can I find useful Go packages?"
+---
 
-Steve Francia and Julie Qiu
-julieqiu@golang.org
-
-##
 
 Over the last two years,
 as we’ve spoken with users at companies of all sizes,
@@ -19,7 +19,7 @@
 There you will find a wealth of learning resources to get started with the language,
 featured use cases, and case studies of companies using Go.
 
-.image go.dev/home.png _ 850
+{{image "go.dev/home.png" 850}}
 
 (Note that [golang.org](https://golang.org/) is still the home for the
 open source Go project and the Go distribution.
@@ -35,7 +35,7 @@
 You can follow
 [Go issue 33654](https://golang.org/issue/33654) for future developments.
 
-.image go.dev/http.png _ 850
+{{image "go.dev/http.png" 850}}
 
 Today’s launch is our minimum viable product for go.dev,
 so we can share what we’ve built to help the community and get feedback.
diff --git a/blog/_content/go.dev/home.png b/go.dev/_content/blog/go.dev/home.png
similarity index 100%
rename from blog/_content/go.dev/home.png
rename to go.dev/_content/blog/go.dev/home.png
Binary files differ
diff --git a/blog/_content/go.dev/http.png b/go.dev/_content/blog/go.dev/http.png
similarity index 100%
rename from blog/_content/go.dev/http.png
rename to go.dev/_content/blog/go.dev/http.png
Binary files differ
diff --git a/blog/_content/go1-path.article b/go.dev/_content/blog/go1-path.md
similarity index 77%
rename from blog/_content/go1-path.article
rename to go.dev/_content/blog/go1-path.md
index ce867ea..e788264 100644
--- a/blog/_content/go1-path.article
+++ b/go.dev/_content/blog/go1-path.md
@@ -1,12 +1,15 @@
-# The path to Go 1
-14 Mar 2013
-Tags: talk, video, go1
-Summary: Watch Rob Pike and Andrew Gerrand's talk, The Path to Go 1.
-OldURL: /the-path-to-go-1
+---
+title: The path to Go 1
+date: 2013-03-14
+by:
+- Andrew Gerrand
+tags:
+- talk
+- video
+- go1
+summary: Watch Rob Pike and Andrew Gerrand's talk, The Path to Go 1.
+---
 
-Andrew Gerrand
-
-##
 
 In July 2012, Rob Pike and I presented a talk at OSCON titled _The path to Go 1_.
 In it we explain how Go 1 came to be, and outline the process by which Go
@@ -15,7 +18,7 @@
 We present the major highlights of the release and discuss the details behind
 some specific libraries and tools.
 
-.iframe //www.youtube.com/embed/bj9T2c2Xk_s 309 550
+{{video "https://www.youtube.com/embed/bj9T2c2Xk_s"}}
 
 The slides for the talk are [available here](https://talks.golang.org/2012/go1.slide).
 
diff --git a/blog/_content/go1-preview.article b/go.dev/_content/blog/go1-preview.md
similarity index 92%
rename from blog/_content/go1-preview.article
rename to go.dev/_content/blog/go1-preview.md
index 6e3f474..682199a 100644
--- a/blog/_content/go1-preview.article
+++ b/go.dev/_content/blog/go1-preview.md
@@ -1,12 +1,14 @@
-# A preview of Go version 1
-5 Oct 2011
-Tags: go1, release
-Summary: What the Go team is planning for Go version 1.
-OldURL: /preview-of-go-version-1
+---
+title: A preview of Go version 1
+date: 2011-10-05
+by:
+- Russ Cox
+tags:
+- go1
+- release
+summary: What the Go team is planning for Go version 1.
+---
 
-Russ Cox
-
-##
 
 We want to be able to provide a stable base for people using Go.
 People should be able to write Go programs and expect that they will continue
diff --git a/blog/_content/go1.1.article b/go.dev/_content/blog/go1.1.md
similarity index 91%
rename from blog/_content/go1.1.article
rename to go.dev/_content/blog/go1.1.md
index f2f26c6..e56fc70 100644
--- a/blog/_content/go1.1.article
+++ b/go.dev/_content/blog/go1.1.md
@@ -1,16 +1,17 @@
-# Go 1.1 is released
-13 May 2013
-Tags: release
-Summary: Go 1.1 is faster, less picky about return statements, and adds method expressions.
-OldURL: /go-11-is-released
+---
+title: Go 1.1 is released
+date: 2013-05-13
+by:
+- Andrew Gerrand
+tags:
+- release
+summary: Go 1.1 is faster, less picky about return statements, and adds method expressions.
+---
 
-Andrew Gerrand
-
-##
 
 It is our great pleasure to announce the release of Go 1.1.
 
-.image go1.1/gopherbiplane5.jpg
+{{image "go1.1/gopherbiplane5.jpg"}}
 
 In March last year we released Go 1.0, and since then we have released three
 minor "point releases".
diff --git a/blog/_content/go1.1/gopherbiplane5.jpg b/go.dev/_content/blog/go1.1/gopherbiplane5.jpg
similarity index 100%
rename from blog/_content/go1.1/gopherbiplane5.jpg
rename to go.dev/_content/blog/go1.1/gopherbiplane5.jpg
Binary files differ
diff --git a/blog/_content/go1.10.article b/go.dev/_content/blog/go1.10.md
similarity index 89%
rename from blog/_content/go1.10.article
rename to go.dev/_content/blog/go1.10.md
index dd423fc..8503b0a 100644
--- a/blog/_content/go1.10.article
+++ b/go.dev/_content/blog/go1.10.md
@@ -1,11 +1,11 @@
-# Go 1.10 is released
-16 Feb 2018
-Summary: Go 1.10 adds automatic caching of build & test results, and more.
+---
+title: Go 1.10 is released
+date: 2018-02-16
+by:
+- Brad Fitzpatrick
+summary: Go 1.10 adds automatic caching of build & test results, and more.
+---
 
-Brad Fitzpatrick
-bradfitz@golang.org
-
-##
 
 Happy Friday, happy weekend! Today the Go team is happy to announce the release of Go 1.10.
 You can get it from the [download page](https://golang.org/dl/).
diff --git a/blog/_content/go1.11.article b/go.dev/_content/blog/go1.11.md
similarity index 91%
rename from blog/_content/go1.11.article
rename to go.dev/_content/blog/go1.11.md
index b612ebc..07a62f0 100644
--- a/blog/_content/go1.11.article
+++ b/go.dev/_content/blog/go1.11.md
@@ -1,11 +1,11 @@
-# Go 1.11 is released
-24 Aug 2018
-Summary: Go 1.11 adds preliminary support for Go modules, WebAssembly, and more.
+---
+title: Go 1.11 is released
+date: 2018-08-24
+by:
+- Andrew Bonventre
+summary: Go 1.11 adds preliminary support for Go modules, WebAssembly, and more.
+---
 
-Andrew Bonventre
-andybons@golang.org
-
-##
 
 Who says releasing on Friday is a bad idea?
 
diff --git a/blog/_content/go1.12.article b/go.dev/_content/blog/go1.12.md
similarity index 86%
rename from blog/_content/go1.12.article
rename to go.dev/_content/blog/go1.12.md
index 79f0e25..6bb8951 100644
--- a/blog/_content/go1.12.article
+++ b/go.dev/_content/blog/go1.12.md
@@ -1,11 +1,11 @@
-# Go 1.12 is released
-25 Feb 2019
-Summary: Go 1.12 adds opt-in TLS 1.3, improved modules, and more.
+---
+title: Go 1.12 is released
+date: 2019-02-25
+by:
+- Andrew Bonventre
+summary: Go 1.12 adds opt-in TLS 1.3, improved modules, and more.
+---
 
-Andrew Bonventre
-andybons@golang.org
-
-##
 
 Today the Go team is happy to announce the release of Go 1.12.
 You can get it from the [download page](https://golang.org/dl/).
diff --git a/blog/_content/go1.13-errors.article b/go.dev/_content/blog/go1.13-errors.md
similarity index 97%
rename from blog/_content/go1.13-errors.article
rename to go.dev/_content/blog/go1.13-errors.md
index f5ffd84..62975a4 100644
--- a/blog/_content/go1.13-errors.article
+++ b/go.dev/_content/blog/go1.13-errors.md
@@ -1,9 +1,13 @@
-# Working with Errors in Go 1.13
-17 Oct 2019
-Tags: errors, technical
-Summary: How to use the new Go 1.13 error interfaces and functions.
-
-Damien Neil and Jonathan Amsterdam
+---
+title: Working with Errors in Go 1.13
+date: 2019-10-17
+by:
+- Damien Neil and Jonathan Amsterdam
+tags:
+- errors
+- technical
+summary: How to use the new Go 1.13 error interfaces and functions.
+---
 
 ## Introduction
 
diff --git a/blog/_content/go1.13.article b/go.dev/_content/blog/go1.13.md
similarity index 88%
rename from blog/_content/go1.13.article
rename to go.dev/_content/blog/go1.13.md
index 156a0e9..049cd4c 100644
--- a/blog/_content/go1.13.article
+++ b/go.dev/_content/blog/go1.13.md
@@ -1,10 +1,11 @@
-# Go 1.13 is released
-3 Sep 2019
-Summary: Go 1.13 adds module authentication, new number literals, error wrapping, TLS 1.3 on by default, and more.
+---
+title: Go 1.13 is released
+date: 2019-09-03
+by:
+- Andrew Bonventre
+summary: Go 1.13 adds module authentication, new number literals, error wrapping, TLS 1.3 on by default, and more.
+---
 
-Andrew Bonventre
-
-##
 
 Today the Go team is very happy to announce the release of Go 1.13. You can get it from the [download page](https://golang.org/dl).
 
diff --git a/blog/_content/go1.14.article b/go.dev/_content/blog/go1.14.md
similarity index 90%
rename from blog/_content/go1.14.article
rename to go.dev/_content/blog/go1.14.md
index 9c6cefb..82709f6 100644
--- a/blog/_content/go1.14.article
+++ b/go.dev/_content/blog/go1.14.md
@@ -1,10 +1,11 @@
-# Go 1.14 is released
-25 Feb 2020
-Summary: Go 1.14 adds production-ready module support, faster defers, better goroutine preemption, and more.
+---
+title: Go 1.14 is released
+date: 2020-02-25
+by:
+- Alex Rakoczy
+summary: Go 1.14 adds production-ready module support, faster defers, better goroutine preemption, and more.
+---
 
-Alex Rakoczy
-
-##
 
 Today the Go team is very happy to announce the release of Go 1.14. You can get it from the [download page](https://golang.org/dl).
 
diff --git a/blog/_content/go1.15-proposals.article b/go.dev/_content/blog/go1.15-proposals.md
similarity index 95%
rename from blog/_content/go1.15-proposals.article
rename to go.dev/_content/blog/go1.15-proposals.md
index 7b1e493..5171eb9 100644
--- a/blog/_content/go1.15-proposals.article
+++ b/go.dev/_content/blog/go1.15-proposals.md
@@ -1,10 +1,16 @@
-# Proposals for Go 1.15
-28 Jan 2020
-Tags: go1.15, proposals, community, language, vet
-Summary: For Go 1.15, we propose three minor language cleanup changes.
-
-Robert Griesemer, for the Go team
-gri@golang.org
+---
+title: Proposals for Go 1.15
+date: 2020-01-28
+by:
+- Robert Griesemer, for the Go team
+tags:
+- go1.15
+- proposals
+- community
+- language
+- vet
+summary: For Go 1.15, we propose three minor language cleanup changes.
+---
 
 ## Status
 
diff --git a/blog/_content/go1.15.article b/go.dev/_content/blog/go1.15.md
similarity index 89%
rename from blog/_content/go1.15.article
rename to go.dev/_content/blog/go1.15.md
index 1f71528..4a86941 100644
--- a/blog/_content/go1.15.article
+++ b/go.dev/_content/blog/go1.15.md
@@ -1,10 +1,11 @@
-# Go 1.15 is released
-11 Aug 2020
-Summary: Go 1.15 adds a new linker, X.509 changes, runtime improvements, compiler improvements, GOPROXY improvements, and more.
+---
+title: Go 1.15 is released
+date: 2020-08-11
+by:
+- Alex Rakoczy
+summary: Go 1.15 adds a new linker, X.509 changes, runtime improvements, compiler improvements, GOPROXY improvements, and more.
+---
 
-Alex Rakoczy
-
-##
 
 Today the Go team is very happy to announce the release of Go 1.15. You can get it from the [download page](https://golang.org/dl).
 
diff --git a/blog/_content/go1.16.article b/go.dev/_content/blog/go1.16.md
similarity index 91%
rename from blog/_content/go1.16.article
rename to go.dev/_content/blog/go1.16.md
index d7b5323..39b0ffe 100644
--- a/blog/_content/go1.16.article
+++ b/go.dev/_content/blog/go1.16.md
@@ -1,12 +1,12 @@
-# Go 1.16 is released
-16 Feb 2021
-Summary: Go 1.16 adds embedded files, Apple silicon support, and more.
+---
+title: Go 1.16 is released
+date: 2021-02-16
+by:
+- Matt Pearring
+- Dmitri Shuralyov
+summary: Go 1.16 adds embedded files, Apple silicon support, and more.
+---
 
-Matt Pearring
-
-Dmitri Shuralyov
-
-##
 
 Today the Go team is very happy to announce the release of Go 1.16.
 You can get it from the [download page](https://golang.org/dl/).
diff --git a/blog/_content/go1.17.article b/go.dev/_content/blog/go1.17.md
similarity index 91%
rename from blog/_content/go1.17.article
rename to go.dev/_content/blog/go1.17.md
index 4c0edf3..d938634 100644
--- a/blog/_content/go1.17.article
+++ b/go.dev/_content/blog/go1.17.md
@@ -1,12 +1,12 @@
-# Go 1.17 is released
-16 Aug 2021
-Summary: Go 1.17 adds performance improvements, module optimizations, arm64 on Windows, and more.
+---
+title: Go 1.17 is released
+date: 2021-08-16
+by:
+- Matt Pearring
+- Alex Rakoczy
+summary: Go 1.17 adds performance improvements, module optimizations, arm64 on Windows, and more.
+---
 
-Matt Pearring
-
-Alex Rakoczy
-
-##
 
 Today the Go team is thrilled to release Go 1.17, which you can get by visiting the
 [download page](https://golang.org/dl/).
@@ -24,7 +24,7 @@
 release. Modules that specify `go 1.17` or higher in their `go.mod` file will have their module graphs
 include only the immediate dependencies of other Go 1.17 modules, not their full transitive
 dependencies. This should help avoid the need to download or read `go.mod` files for otherwise
-irrelevant dependencies&#8212;saving time in everyday development.
+irrelevant dependencies—saving time in everyday development.
 
 Go 1.17 comes with three small [changes to the language](https://golang.org/doc/go1.17#language).
 The first two are new functions in the `unsafe` package to make it simpler for programs to conform
@@ -47,3 +47,4 @@
 [file an issue](https://golang.org/issue/new).
 
 We hope you enjoy the new release!
+
diff --git a/blog/_content/go1.3.article b/go.dev/_content/blog/go1.3.md
similarity index 94%
rename from blog/_content/go1.3.article
rename to go.dev/_content/blog/go1.3.md
index 9fb837a..c7642ee 100644
--- a/blog/_content/go1.3.article
+++ b/go.dev/_content/blog/go1.3.md
@@ -1,10 +1,11 @@
-# Go 1.3 is released
-18 Jun 2014
-Summary: Go 1.3 adds better performance, static analysis in godoc, and more.
+---
+title: Go 1.3 is released
+date: 2014-06-18
+by:
+- Andrew Gerrand
+summary: Go 1.3 adds better performance, static analysis in godoc, and more.
+---
 
-Andrew Gerrand
-
-##
 
 Today we are happy to announce the release of [Go 1.3](https://golang.org/doc/go1.3).
 This release comes six months after our last major release and provides better
diff --git a/blog/_content/go1.4.article b/go.dev/_content/blog/go1.4.md
similarity index 94%
rename from blog/_content/go1.4.article
rename to go.dev/_content/blog/go1.4.md
index 85b4c0f..077e684 100644
--- a/blog/_content/go1.4.article
+++ b/go.dev/_content/blog/go1.4.md
@@ -1,11 +1,11 @@
-# Go 1.4 is released
-10 Dec 2014
-Summary: Go 1.4 adds support for Android, go generate, optimizations, and more.
+---
+title: Go 1.4 is released
+date: 2014-12-10
+by:
+- Andrew Gerrand
+summary: Go 1.4 adds support for Android, go generate, optimizations, and more.
+---
 
-Andrew Gerrand
-adg@golang.org
-
-##
 
 Today we announce Go 1.4, the fifth major stable release of Go, arriving six
 months after our previous major release [Go 1.3](https://blog.golang.org/go1.3).
diff --git a/blog/_content/go1.5.article b/go.dev/_content/blog/go1.5.md
similarity index 95%
rename from blog/_content/go1.5.article
rename to go.dev/_content/blog/go1.5.md
index 348eea8..6a8c239 100644
--- a/blog/_content/go1.5.article
+++ b/go.dev/_content/blog/go1.5.md
@@ -1,11 +1,11 @@
-# Go 1.5 is released
-19 Aug 2015
-Summary: Go 1.5 adds a new, much faster garbage collector, more parallelism by default, go tool trace, and more.
+---
+title: Go 1.5 is released
+date: 2015-08-19
+by:
+- Andrew Gerrand
+summary: Go 1.5 adds a new, much faster garbage collector, more parallelism by default, go tool trace, and more.
+---
 
-Andrew Gerrand
-adg@golang.org
-
-##
 
 Today the Go project is proud to release Go 1.5,
 the sixth major stable release of Go.
diff --git a/blog/_content/go1.6.article b/go.dev/_content/blog/go1.6.md
similarity index 94%
rename from blog/_content/go1.6.article
rename to go.dev/_content/blog/go1.6.md
index 6c5afeb..b6ffc05 100644
--- a/blog/_content/go1.6.article
+++ b/go.dev/_content/blog/go1.6.md
@@ -1,11 +1,11 @@
-# Go 1.6 is released
-17 Feb 2016
-Summary: Go 1.6 adds HTTP/2, template blocks, and more.
+---
+title: Go 1.6 is released
+date: 2016-02-17
+by:
+- Andrew Gerrand
+summary: Go 1.6 adds HTTP/2, template blocks, and more.
+---
 
-Andrew Gerrand
-adg@golang.org
-
-##
 
 Today we release [Go version 1.6](https://golang.org/doc/go1.6),
 the seventh major stable release of Go.
@@ -27,7 +27,7 @@
 The template packages have learned some new tricks,
 with support for [trimming spaces around template actions](https://golang.org/pkg/text/template/#hdr-Text_and_spaces)
 to produce cleaner template output,
-and the introduction of the [`{{block}}` action](https://golang.org/pkg/text/template/#hdr-Actions)
+and the introduction of the {{raw "[`{{block}}` action]"}}(https://golang.org/pkg/text/template/#hdr-Actions)
 that can be used to create templates that build on other templates.
 A [new template example program](https://github.com/golang/example/tree/master#template-godoc) demonstrates these new features.
 
diff --git a/blog/_content/go1.7-binary-size.article b/go.dev/_content/blog/go1.7-binary-size.md
similarity index 95%
rename from blog/_content/go1.7-binary-size.article
rename to go.dev/_content/blog/go1.7-binary-size.md
index b920d86..ea56245 100644
--- a/blog/_content/go1.7-binary-size.article
+++ b/go.dev/_content/blog/go1.7-binary-size.md
@@ -1,9 +1,10 @@
-# Smaller Go 1.7 binaries
-18 Aug 2016
-Summary: Go 1.7 includes some binary size reductions important for small devices.
-
-David Crawshaw
-crawshaw@golang.org
+---
+title: Smaller Go 1.7 binaries
+date: 2016-08-18
+by:
+- David Crawshaw
+summary: Go 1.7 includes some binary size reductions important for small devices.
+---
 
 ## Introduction
 
@@ -82,7 +83,7 @@
 When compiled without debugging information the statically
 linked binary is now under a megabyte.
 
-.image go1.7-binary-size/graph.png
+{{image "go1.7-binary-size/graph.png"}}
 
 A large production program used for testing this cycle, `jujud`, went from 94MB
 to 67MB.
diff --git a/blog/_content/go1.7-binary-size/graph.png b/go.dev/_content/blog/go1.7-binary-size/graph.png
similarity index 100%
rename from blog/_content/go1.7-binary-size/graph.png
rename to go.dev/_content/blog/go1.7-binary-size/graph.png
Binary files differ
diff --git a/blog/_content/go1.7.article b/go.dev/_content/blog/go1.7.md
similarity index 95%
rename from blog/_content/go1.7.article
rename to go.dev/_content/blog/go1.7.md
index f9ddae0..0aa8ad2 100644
--- a/blog/_content/go1.7.article
+++ b/go.dev/_content/blog/go1.7.md
@@ -1,11 +1,11 @@
-# Go 1.7 is released
-15 Aug 2016
-Summary: Go 1.7 adds faster x86 compiled code, context in the standard library, and more.
+---
+title: Go 1.7 is released
+date: 2016-08-15
+by:
+- Chris Broadfoot
+summary: Go 1.7 adds faster x86 compiled code, context in the standard library, and more.
+---
 
-Chris Broadfoot
-cbro@golang.org
-
-##
 
 Today we are happy to announce the release of Go 1.7.
 You can get it from the [download page](https://golang.org/dl/).
diff --git a/blog/_content/go1.8.article b/go.dev/_content/blog/go1.8.md
similarity index 94%
rename from blog/_content/go1.8.article
rename to go.dev/_content/blog/go1.8.md
index c6e5451..0a8afec 100644
--- a/blog/_content/go1.8.article
+++ b/go.dev/_content/blog/go1.8.md
@@ -1,11 +1,11 @@
-# Go 1.8 is released
-16 Feb 2017
-Summary: Go 1.8 adds faster non-x86 compiled code, sub-millisecond garbage collection pauses, HTTP/2 push, and more.
+---
+title: Go 1.8 is released
+date: 2017-02-16
+by:
+- Chris Broadfoot
+summary: Go 1.8 adds faster non-x86 compiled code, sub-millisecond garbage collection pauses, HTTP/2 push, and more.
+---
 
-Chris Broadfoot
-cbro@golang.org
-
-##
 
 Today the Go team is happy to announce the release of Go 1.8.
 You can get it from the [download page](https://golang.org/dl/).
@@ -37,7 +37,9 @@
 It's now much simpler to sort slices using the newly added [`Slice`](https://golang.org/pkg/sort/#Slice)
 function in the `sort` package. For example, to sort a slice of structs by their `Name` field:
 
+{{raw `
 	sort.Slice(s, func(i, j int) bool { return s[i].Name < s[j].Name })
+`}}
 
 Go 1.8 includes many more additions, improvements, and fixes.
 Find the complete set of changes, and more information about the improvements listed above, in the
diff --git a/blog/_content/go1.9.article b/go.dev/_content/blog/go1.9.md
similarity index 94%
rename from blog/_content/go1.9.article
rename to go.dev/_content/blog/go1.9.md
index 4ee94cc..73444ea 100644
--- a/blog/_content/go1.9.article
+++ b/go.dev/_content/blog/go1.9.md
@@ -1,11 +1,11 @@
-# Go 1.9 is released
-24 Aug 2017
-Summary: Go 1.9 adds type aliases, bit intrinsics, optimizations, and more.
+---
+title: Go 1.9 is released
+date: 2017-08-24
+by:
+- Francesc Campoy
+summary: Go 1.9 adds type aliases, bit intrinsics, optimizations, and more.
+---
 
-Francesc Campoy
-campoy@golang.org
-
-##
 
 Today the Go team is happy to announce the release of Go 1.9.
 You can get it from the [download page](https://golang.org/dl/).
@@ -43,7 +43,7 @@
 
 For example, consider this test:
 
-.code go1.9/helper_test.go /package p/,
+{{code "go1.9/helper_test.go" `/package p/` `$`}}
 
 Because `failure` identifies itself as a test helper, the error message printed during `Test` will indicate line 11,
 where `failure` is called, instead of line 7, where `failure` calls `t.Fatal`.
diff --git a/blog/_content/go1.9/helper_test.go b/go.dev/_content/blog/go1.9/helper_test.go
similarity index 100%
rename from blog/_content/go1.9/helper_test.go
rename to go.dev/_content/blog/go1.9/helper_test.go
diff --git a/blog/_content/go1.article b/go.dev/_content/blog/go1.md
similarity index 93%
rename from blog/_content/go1.article
rename to go.dev/_content/blog/go1.md
index be06ceb..f1ce59b 100644
--- a/blog/_content/go1.article
+++ b/go.dev/_content/blog/go1.md
@@ -1,13 +1,16 @@
-# Go version 1 is released
-28 Mar 2012
-Tags: release, go1
-Summary: A major milestone: announcing Go 1, the first stable version of Go.
+---
+title: Go version 1 is released
+date: 2012-03-28
+by:
+- Andrew Gerrand
+tags:
+- release
+- go1
+summary: "A major milestone: announcing Go 1, the first stable version of Go."
+---
 
-Andrew Gerrand
 
-##
-
-.image go1/gophermega.jpg
+{{image "go1/gophermega.jpg"}}
 
 Today marks a major milestone in the development of the Go programming language.
 We're announcing Go version 1, or Go 1 for short,
diff --git a/blog/_content/go1/gophermega.jpg b/go.dev/_content/blog/go1/gophermega.jpg
similarity index 100%
rename from blog/_content/go1/gophermega.jpg
rename to go.dev/_content/blog/go1/gophermega.jpg
Binary files differ
diff --git a/blog/_content/go116-module-changes.article b/go.dev/_content/blog/go116-module-changes.md
similarity index 97%
rename from blog/_content/go116-module-changes.article
rename to go.dev/_content/blog/go116-module-changes.md
index bb3bff9..b969fd3 100644
--- a/blog/_content/go116-module-changes.article
+++ b/go.dev/_content/blog/go116-module-changes.md
@@ -1,11 +1,14 @@
-# New module changes in Go 1.16
-18 Feb 2021
-Tags: modules, versioning
-Summary: Go 1.16 enables modules by default, provides a new way to install executables, and lets module authors retract published versions.
+---
+title: New module changes in Go 1.16
+date: 2021-02-18
+by:
+- Jay Conrod
+tags:
+- modules
+- versioning
+summary: Go 1.16 enables modules by default, provides a new way to install executables, and lets module authors retract published versions.
+---
 
-Jay Conrod
-
-##
 
 We hope you're enjoying Go 1.16!
 This release has a lot of new features, especially for modules.
diff --git a/blog/_content/go12.article b/go.dev/_content/blog/go12.md
similarity index 95%
rename from blog/_content/go12.article
rename to go.dev/_content/blog/go12.md
index 9af3c8a..eb1b858 100644
--- a/blog/_content/go12.article
+++ b/go.dev/_content/blog/go12.md
@@ -1,11 +1,13 @@
-# Go 1.2 is released
-1 Dec 2013
-Tags: release
-Summary: Go 1.2 adds test coverage results, goroutine preemption, and more.
+---
+title: Go 1.2 is released
+date: 2013-12-01
+by:
+- Andrew Gerrand
+tags:
+- release
+summary: Go 1.2 adds test coverage results, goroutine preemption, and more.
+---
 
-Andrew Gerrand
-
-##
 
 We are pleased to announce the release of Go 1.2, the latest stable version of
 the Go Programming Language.
diff --git a/blog/_content/go15gc.article b/go.dev/_content/blog/go15gc.md
similarity index 96%
rename from blog/_content/go15gc.article
rename to go.dev/_content/blog/go15gc.md
index 85428c1..b641d9f 100644
--- a/blog/_content/go15gc.article
+++ b/go.dev/_content/blog/go15gc.md
@@ -1,9 +1,10 @@
-# Go GC: Prioritizing low latency and simplicity
-31 Aug 2015
-Summary: Go 1.5 is the first step toward a new low-latency future for the Go garbage collector.
-
-Richard Hudson
-rlh@golang.org
+---
+title: "Go GC: Prioritizing low latency and simplicity"
+date: 2015-08-31
+by:
+- Richard Hudson
+summary: Go 1.5 is the first step toward a new low-latency future for the Go garbage collector.
+---
 
 ## The Setup
 
diff --git a/blog/_content/go2-here-we-come.article b/go.dev/_content/blog/go2-here-we-come.md
similarity index 97%
rename from blog/_content/go2-here-we-come.article
rename to go.dev/_content/blog/go2-here-we-come.md
index f081ade..288180c 100644
--- a/blog/_content/go2-here-we-come.article
+++ b/go.dev/_content/blog/go2-here-we-come.md
@@ -1,9 +1,14 @@
-# Go 2, here we come!
-29 Nov 2018
-Tags: go2, proposals, community
-Summary: How Go 2 proposals will be evaluated, selected, and shipped.
-
-Robert Griesemer
+---
+title: Go 2, here we come!
+date: 2018-11-29
+by:
+- Robert Griesemer
+tags:
+- go2
+- proposals
+- community
+summary: How Go 2 proposals will be evaluated, selected, and shipped.
+---
 
 ## Background
 
diff --git a/blog/_content/go2-next-steps.article b/go.dev/_content/blog/go2-next-steps.md
similarity index 96%
rename from blog/_content/go2-next-steps.article
rename to go.dev/_content/blog/go2-next-steps.md
index b9bf517..b71573a 100644
--- a/blog/_content/go2-next-steps.article
+++ b/go.dev/_content/blog/go2-next-steps.md
@@ -1,9 +1,14 @@
-# Next steps toward Go 2
-26 Jun 2019
-Tags: go2, proposals, community
-Summary: What Go 2 language changes should we include in Go 1.14?
-
-Robert Griesemer, for the Go team
+---
+title: Next steps toward Go 2
+date: 2019-06-26
+by:
+- Robert Griesemer, for the Go team
+tags:
+- go2
+- proposals
+- community
+summary: What Go 2 language changes should we include in Go 1.14?
+---
 
 ## Status
 
diff --git a/blog/_content/go2draft.article b/go.dev/_content/blog/go2draft.md
similarity index 73%
rename from blog/_content/go2draft.article
rename to go.dev/_content/blog/go2draft.md
index 7bf2bf3..d838648 100644
--- a/blog/_content/go2draft.article
+++ b/go.dev/_content/blog/go2draft.md
@@ -1,9 +1,12 @@
-# Go 2 Draft Designs
-28 Aug 2018
-Tags: community, video
-Summary: Announcing the draft designs for the major Go 2 changes.
+---
+title: Go 2 Draft Designs
+date: 2018-08-28
+tags:
+- community
+- video
+summary: Announcing the draft designs for the major Go 2 changes.
+---
 
-##
 
 Yesterday, at our annual Go contributor summit,
 attendees got a sneak peek at preliminary _drafts_ of
@@ -12,7 +15,7 @@
 
 For a quick overview, watch this short message we just played at Gophercon 2018:
 
-.iframe //www.youtube.com/embed/6wIP3rO6On8 315 560
+{{video "https://www.youtube.com/embed/6wIP3rO6On8"}}
 
 We invite everyone in the Go community to
 [learn more about the designs](https://go.googlesource.com/proposal/+/master/design/go2draft.md)
diff --git a/blog/_content/gob.article b/go.dev/_content/blog/gob.md
similarity index 97%
rename from blog/_content/gob.article
rename to go.dev/_content/blog/gob.md
index 3b5c405..2e7b493 100644
--- a/blog/_content/gob.article
+++ b/go.dev/_content/blog/gob.md
@@ -1,10 +1,16 @@
-# Gobs of data
-24 Mar 2011
-Tags: gob, json, protobuf, xml, technical
-Summary: Introducing gob, a high-speed Go-to-Go wire encoding format.
-OldURL: /gobs-of-data
-
-Rob Pike
+---
+title: Gobs of data
+date: 2011-03-24
+by:
+- Rob Pike
+tags:
+- gob
+- json
+- protobuf
+- xml
+- technical
+summary: Introducing gob, a high-speed Go-to-Go wire encoding format.
+---
 
 ## Introduction
 
diff --git a/go.dev/_content/blog/gobs-of-data.md b/go.dev/_content/blog/gobs-of-data.md
new file mode 100644
index 0000000..6313782
--- /dev/null
+++ b/go.dev/_content/blog/gobs-of-data.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/gob
+---
diff --git a/go.dev/_content/blog/godoc-documenting-go-code.md b/go.dev/_content/blog/godoc-documenting-go-code.md
new file mode 100644
index 0000000..a9bbb1a
--- /dev/null
+++ b/go.dev/_content/blog/godoc-documenting-go-code.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/godoc
+---
diff --git a/blog/_content/godoc.article b/go.dev/_content/blog/godoc.md
similarity index 96%
rename from blog/_content/godoc.article
rename to go.dev/_content/blog/godoc.md
index 0e0a345..720e444 100644
--- a/blog/_content/godoc.article
+++ b/go.dev/_content/blog/godoc.md
@@ -1,12 +1,14 @@
-# Godoc: documenting Go code
-31 Mar 2011
-Tags: godoc, technical
-Summary: How and why to document your Go packages.
-OldURL: /godoc-documenting-go-code
+---
+title: "Godoc: documenting Go code"
+date: 2011-03-31
+by:
+- Andrew Gerrand
+tags:
+- godoc
+- technical
+summary: How and why to document your Go packages.
+---
 
-Andrew Gerrand
-
-##
 
 The Go project takes documentation seriously.
 Documentation is a huge part of making software accessible and maintainable.
diff --git a/blog/_content/godoc.org-redirect.article b/go.dev/_content/blog/godoc.org-redirect.md
similarity index 94%
rename from blog/_content/godoc.org-redirect.article
rename to go.dev/_content/blog/godoc.org-redirect.md
index c7183e0..956290d 100644
--- a/blog/_content/godoc.org-redirect.article
+++ b/go.dev/_content/blog/godoc.org-redirect.md
@@ -1,10 +1,11 @@
-# Redirecting godoc.org requests to pkg.go.dev
-15 Dec 2020
-Summary: The plan for moving from godoc.org to pkg.go.dev.
+---
+title: Redirecting godoc.org requests to pkg.go.dev
+date: 2020-12-15
+by:
+- Julie Qiu
+summary: The plan for moving from godoc.org to pkg.go.dev.
+---
 
-Julie Qiu
-
-##
 
 With the introduction of Go modules and the growth of the Go ecosystem,
 [pkg.go.dev](https://pkg.go.dev) was
diff --git a/blog/_content/gofmt.article b/go.dev/_content/blog/gofmt.md
similarity index 95%
rename from blog/_content/gofmt.article
rename to go.dev/_content/blog/gofmt.md
index 75bbfb2..0e4b189 100644
--- a/blog/_content/gofmt.article
+++ b/go.dev/_content/blog/gofmt.md
@@ -1,10 +1,14 @@
-# go fmt your code
-23 Jan 2013
-Tags: gofix, gofmt, technical
-Summary: How and why to format your Go code using gofmt.
-OldURL: /go-fmt-your-code
-
-Andrew Gerrand
+---
+title: go fmt your code
+date: 2013-01-23
+by:
+- Andrew Gerrand
+tags:
+- gofix
+- gofmt
+- technical
+summary: How and why to format your Go code using gofmt.
+---
 
 ## Introduction
 
diff --git a/blog/_content/gopher.article b/go.dev/_content/blog/gopher.md
similarity index 87%
rename from blog/_content/gopher.article
rename to go.dev/_content/blog/gopher.md
index 27175de..826d3f5 100644
--- a/blog/_content/gopher.article
+++ b/go.dev/_content/blog/gopher.md
@@ -1,15 +1,16 @@
-# The Go Gopher
-24 Mar 2014
-Tags: gopher
-Summary: The backstory of the Go gopher.
+---
+title: The Go Gopher
+date: 2014-03-24
+by:
+- Rob Pike
+- Andrew Gerrand
+tags:
+- gopher
+summary: The backstory of the Go gopher.
+---
 
-Rob Pike
 
-Andrew Gerrand
-
-##
-
-.image gopher/header.jpg
+{{image "gopher/header.jpg"}}
 
 The Go gopher is an iconic mascot and one of the most distinctive features of the Go project.
 In this post we'll talk about its origins,
@@ -20,29 +21,29 @@
 [Renee French](http://reneefrench.blogspot.com) was commissioned to
 design a T-shirt for an annual fundraiser and out came the gopher.
 
-.image gopher/wfmu.jpg
+{{image "gopher/wfmu.jpg"}}
 
 The gopher next made an appearance at Bell Labs,
 as Bob Flandrena's [avatar](https://research.swtch.com/face) in the Bell Labs mail system.
 Other Renee drawings became avatars for ken, r, rsc, and others.
 (Of course, Peter Weinberger's was his own [iconic face](http://spinroot.com/pico/pjw.html).)
 
-.image gopher/avatars.png
+{{image "gopher/avatars.png"}}
 
 Another Bell Labs activity led to Renee creating [Glenda](https://9p.io/plan9/glenda.html),
 the Plan 9 mascot, a distant cousin of the WFMU gopher.
 
-.image gopher/glenda.png
+{{image "gopher/glenda.png"}}
 
 When we started the Go project we needed a logo,
 and Renee volunteered to draw it.
 It was featured on the first Go T-shirt and the Google Code site.
 
-.image gopher/logo.png
+{{image "gopher/logo.png"}}
 
 For the open source launch in 2009, Renee suggested adapting the WFMU gopher as a mascot. And the Go gopher was born:
 
-.image gopher/gopher.png
+{{image "gopher/gopher.png"}}
 
 (The gopher has no name, and is called just the "Go gopher".)
 
@@ -52,17 +53,17 @@
 This was the first time the gopher was colored blue and appeared in three dimensions.
 The first prototype was kinda hairy:
 
-.image gopher/prototype.jpg
+{{image "gopher/prototype.jpg"}}
 
 But the second one was just right:
 
-.image gopher/plush.jpg
+{{image "gopher/plush.jpg"}}
 
 Around the same time, Renee roughed out a gopher in clay.
 This inspired a refined sculpture that became a vinyl figurine made by [Kidrobot](http://www.kidrobot.com/).
 The vinyls were first distributed at OSCON 2011.
 
-.image gopher/vinyl.jpg
+{{image "gopher/vinyl.jpg"}}
 
 The gopher therefore exists in many forms,
 but has always been Renee's creation.
@@ -78,7 +79,7 @@
 
 Here are a few gopher adaptations that people have used as mascots for user group mascots and similar organizations.
 
-.image gopher/usergroups.png
+{{image "gopher/usergroups.png"}}
 
 They're cute and we like them, but by the Creative Commons rules the groups
 should give Renee credit,
@@ -96,6 +97,6 @@
 There are two big chances this year: [GopherCon](http://gophercon.com/) (Denver,
 April 24-26) and [dotGo](http://dotgo.eu) (Paris, October 10).
 
-.image gopher/portrait.jpg
+{{image "gopher/portrait.jpg"}}
 
 _(Photo by_ [_Noah Lorang_](https://twitter.com/noahhlo/status/437395572081688576)_.)_
diff --git a/blog/_content/gopher/avatars.png b/go.dev/_content/blog/gopher/avatars.png
similarity index 100%
rename from blog/_content/gopher/avatars.png
rename to go.dev/_content/blog/gopher/avatars.png
Binary files differ
diff --git a/blog/_content/gopher/glenda.png b/go.dev/_content/blog/gopher/glenda.png
similarity index 100%
rename from blog/_content/gopher/glenda.png
rename to go.dev/_content/blog/gopher/glenda.png
Binary files differ
diff --git a/blog/_content/gopher/gopher.png b/go.dev/_content/blog/gopher/gopher.png
similarity index 100%
rename from blog/_content/gopher/gopher.png
rename to go.dev/_content/blog/gopher/gopher.png
Binary files differ
diff --git a/blog/_content/gopher/header.jpg b/go.dev/_content/blog/gopher/header.jpg
similarity index 100%
rename from blog/_content/gopher/header.jpg
rename to go.dev/_content/blog/gopher/header.jpg
Binary files differ
diff --git a/blog/_content/gopher/logo.png b/go.dev/_content/blog/gopher/logo.png
similarity index 100%
rename from blog/_content/gopher/logo.png
rename to go.dev/_content/blog/gopher/logo.png
Binary files differ
diff --git a/blog/_content/gopher/plush.jpg b/go.dev/_content/blog/gopher/plush.jpg
similarity index 100%
rename from blog/_content/gopher/plush.jpg
rename to go.dev/_content/blog/gopher/plush.jpg
Binary files differ
diff --git a/blog/_content/gopher/portrait.jpg b/go.dev/_content/blog/gopher/portrait.jpg
similarity index 100%
rename from blog/_content/gopher/portrait.jpg
rename to go.dev/_content/blog/gopher/portrait.jpg
Binary files differ
diff --git a/blog/_content/gopher/prototype.jpg b/go.dev/_content/blog/gopher/prototype.jpg
similarity index 100%
rename from blog/_content/gopher/prototype.jpg
rename to go.dev/_content/blog/gopher/prototype.jpg
Binary files differ
diff --git a/blog/_content/gopher/usergroups.png b/go.dev/_content/blog/gopher/usergroups.png
similarity index 100%
rename from blog/_content/gopher/usergroups.png
rename to go.dev/_content/blog/gopher/usergroups.png
Binary files differ
diff --git a/blog/_content/gopher/vinyl.jpg b/go.dev/_content/blog/gopher/vinyl.jpg
similarity index 100%
rename from blog/_content/gopher/vinyl.jpg
rename to go.dev/_content/blog/gopher/vinyl.jpg
Binary files differ
diff --git a/blog/_content/gopher/wfmu.jpg b/go.dev/_content/blog/gopher/wfmu.jpg
similarity index 100%
rename from blog/_content/gopher/wfmu.jpg
rename to go.dev/_content/blog/gopher/wfmu.jpg
Binary files differ
diff --git a/blog/_content/gopherchina.article b/go.dev/_content/blog/gopherchina.md
similarity index 93%
rename from blog/_content/gopherchina.article
rename to go.dev/_content/blog/gopherchina.md
index b680af8..6541b47 100644
--- a/blog/_content/gopherchina.article
+++ b/go.dev/_content/blog/gopherchina.md
@@ -1,12 +1,14 @@
-# GopherChina Trip Report
-1 Jul 2015
-Tags: community, china
-Summary: Reporting from GopherChina 2015, the first Go conference in China.
+---
+title: GopherChina Trip Report
+date: 2015-07-01
+by:
+- Robert Griesemer
+tags:
+- community
+- china
+summary: Reporting from GopherChina 2015, the first Go conference in China.
+---
 
-Robert Griesemer
-gri@golang.org
-
-##
 
 We have known for some time that Go is more popular in China than in any other
 country.
@@ -22,7 +24,7 @@
 decided to accept and give a presentation about gofmt’s impact on software
 development.
 
-.image gopherchina/image04.jpg
+{{image "gopherchina/image04.jpg"}}
 
 _Hello, Shanghai!_
 
@@ -38,7 +40,7 @@
 organizers, many more people were hoping to attend than could be accommodated
 due to space constraints.
 
-.image gopherchina/image01.jpg
+{{image "gopherchina/image01.jpg"}}
 
 _The welcoming committee with Asta Xie (2nd from left), the primary organizer._
 
@@ -48,7 +50,7 @@
 was advertising technical books, including several original (not translated
 from English) Go books.
 
-.image gopherchina/image05.jpg
+{{image "gopherchina/image05.jpg"}}
 
 _Go books!_
 
@@ -79,7 +81,7 @@
 fleet of thousands of machines. A future guest blog post is planned describing
 this system in more detail.
 
-.image gopherchina/image03.jpg
+{{image "gopherchina/image03.jpg"}}
 
 _Packed conference room on Saturday._
 
@@ -109,7 +111,7 @@
 Instead I decided the keep it short and leave plenty of time for general
 questions on Go, which the audience appreciated.
 
-.image gopherchina/image06.jpg
+{{image "gopherchina/image06.jpg"}}
 
 _No social event in China is complete without fantastic food._
 
@@ -121,8 +123,8 @@
 to be the author of one of the first Chinese books on Go (the leftmost one in
 the picture above).
 
-.image gopherchina/image02.jpg
-.image gopherchina/image00.jpg
+{{image "gopherchina/image02.jpg"}}
+{{image "gopherchina/image00.jpg"}}
 
 _Qiniu lobby, engineering._
 
diff --git a/blog/_content/gopherchina/image00.jpg b/go.dev/_content/blog/gopherchina/image00.jpg
similarity index 100%
rename from blog/_content/gopherchina/image00.jpg
rename to go.dev/_content/blog/gopherchina/image00.jpg
Binary files differ
diff --git a/blog/_content/gopherchina/image01.jpg b/go.dev/_content/blog/gopherchina/image01.jpg
similarity index 100%
rename from blog/_content/gopherchina/image01.jpg
rename to go.dev/_content/blog/gopherchina/image01.jpg
Binary files differ
diff --git a/blog/_content/gopherchina/image02.jpg b/go.dev/_content/blog/gopherchina/image02.jpg
similarity index 100%
rename from blog/_content/gopherchina/image02.jpg
rename to go.dev/_content/blog/gopherchina/image02.jpg
Binary files differ
diff --git a/blog/_content/gopherchina/image03.jpg b/go.dev/_content/blog/gopherchina/image03.jpg
similarity index 100%
rename from blog/_content/gopherchina/image03.jpg
rename to go.dev/_content/blog/gopherchina/image03.jpg
Binary files differ
diff --git a/blog/_content/gopherchina/image04.jpg b/go.dev/_content/blog/gopherchina/image04.jpg
similarity index 100%
rename from blog/_content/gopherchina/image04.jpg
rename to go.dev/_content/blog/gopherchina/image04.jpg
Binary files differ
diff --git a/blog/_content/gopherchina/image05.jpg b/go.dev/_content/blog/gopherchina/image05.jpg
similarity index 100%
rename from blog/_content/gopherchina/image05.jpg
rename to go.dev/_content/blog/gopherchina/image05.jpg
Binary files differ
diff --git a/blog/_content/gopherchina/image06.jpg b/go.dev/_content/blog/gopherchina/image06.jpg
similarity index 100%
rename from blog/_content/gopherchina/image06.jpg
rename to go.dev/_content/blog/gopherchina/image06.jpg
Binary files differ
diff --git a/blog/_content/gophercon.article b/go.dev/_content/blog/gophercon.md
similarity index 91%
rename from blog/_content/gophercon.article
rename to go.dev/_content/blog/gophercon.md
index 33f61e1..d65ab6e 100644
--- a/blog/_content/gophercon.article
+++ b/go.dev/_content/blog/gophercon.md
@@ -1,11 +1,11 @@
-# GopherCon 2014 Wrap Up
-28 May 2014
-Summary: Reporting from GopherCon 2014.
+---
+title: GopherCon 2014 Wrap Up
+date: 2014-05-28
+by:
+- Andrew Gerrand
+summary: Reporting from GopherCon 2014.
+---
 
-Andrew Gerrand
-adg@golang.org
-
-##
 
 In April this year 700 gophers descended upon Denver to attend [GopherCon](http://www.gophercon.com/),
 the world's first large-scale Go conference, organized entirely by the community.
@@ -13,7 +13,7 @@
 followed by an informal "hack day" full of code, conversation,
 and more than 4 hours (!) of lightning talks.
 
-.image gophercon/image02.jpg
+{{image "gophercon/image02.jpg"}}
 
 A [complete set of video recordings](http://confreaks.com/events/gophercon2014) is now available
 (the [slides are here](https://github.com/gophercon/2014-talks)).
@@ -39,11 +39,11 @@
 Each attendee received one of the new pink and purple gophers,
 which now accompany the original blue one:
 
-.image gophercon/image01.jpg
+{{image "gophercon/image01.jpg"}}
 
 The gopher was also seen wearing a cape on the side of the incredible [CoreOS](https://coreos.com/) bus:
 
-.image gophercon/image00.jpg
+{{image "gophercon/image00.jpg"}}
 
 Most of the Go team were at the conference,
 and we were moved by the passion and dedication of the Go community.
diff --git a/blog/_content/gophercon/image00.jpg b/go.dev/_content/blog/gophercon/image00.jpg
similarity index 100%
rename from blog/_content/gophercon/image00.jpg
rename to go.dev/_content/blog/gophercon/image00.jpg
Binary files differ
diff --git a/blog/_content/gophercon/image01.jpg b/go.dev/_content/blog/gophercon/image01.jpg
similarity index 100%
rename from blog/_content/gophercon/image01.jpg
rename to go.dev/_content/blog/gophercon/image01.jpg
Binary files differ
diff --git a/blog/_content/gophercon/image02.jpg b/go.dev/_content/blog/gophercon/image02.jpg
similarity index 100%
rename from blog/_content/gophercon/image02.jpg
rename to go.dev/_content/blog/gophercon/image02.jpg
Binary files differ
diff --git a/blog/_content/gophercon2015.article b/go.dev/_content/blog/gophercon2015.md
similarity index 95%
rename from blog/_content/gophercon2015.article
rename to go.dev/_content/blog/gophercon2015.md
index 47b1245..5dbef76 100644
--- a/blog/_content/gophercon2015.article
+++ b/go.dev/_content/blog/gophercon2015.md
@@ -1,18 +1,22 @@
-# GopherCon 2015 Roundup
-28 Jul 2015
-Tags: conference, report, gopher
-Summary: Reporting from GopherCon 2015.
+---
+title: GopherCon 2015 Roundup
+date: 2015-07-28
+by:
+- Andrew Gerrand
+tags:
+- conference
+- report
+- gopher
+summary: Reporting from GopherCon 2015.
+---
 
-Andrew Gerrand
-
-##
 
 A few weeks ago, Go programmers from around the world descended on Denver,
 Colorado for GopherCon 2015. The two-day, single-track conference attracted
 more than 1,250 attendees—nearly double last year's number—and featured 22
 talks presented by Go community members.
 
-.image gophercon2015/cowboy.jpg _ 550
+{{image "gophercon2015/cowboy.jpg" 550}}
 
 <p>
 <small>The Cowboy Gopher (a toy given to each attendee) watches over the ranch.<br>
diff --git a/blog/_content/gophercon2015/cowboy.jpg b/go.dev/_content/blog/gophercon2015/cowboy.jpg
similarity index 100%
rename from blog/_content/gophercon2015/cowboy.jpg
rename to go.dev/_content/blog/gophercon2015/cowboy.jpg
Binary files differ
diff --git a/blog/_content/gophergala.article b/go.dev/_content/blog/gophergala.md
similarity index 85%
rename from blog/_content/gophergala.article
rename to go.dev/_content/blog/gophergala.md
index 96d3cee..4cd8e1c 100644
--- a/blog/_content/gophergala.article
+++ b/go.dev/_content/blog/gophergala.md
@@ -1,18 +1,18 @@
-# The Gopher Gala is the first worldwide Go hackathon
-7 Jan 2015
-Summary: The Gopher Gala, the first global Go hackathon, will take place January 23-25, 2015.
+---
+title: The Gopher Gala is the first worldwide Go hackathon
+date: 2015-01-07
+by:
+- Francesc Campoy
+summary: The Gopher Gala, the first global Go hackathon, will take place January 23-25, 2015.
+---
 
-Francesc Campoy
-campoy@golang.org
-
-##
 
 The [Gopher Gala](http://gophergala.com/) is the first Go hackathon at a
 global scale and will take place from January 23rd through the 25th. The event
 is organized by the community, supported by the Go team, and sponsored by
 Google among others.
 
-.image gophergala/fancygopher.jpg _ 300
+{{image "gophergala/fancygopher.jpg" 300}}
 _Fancy_Gopher,_by_ [[http://www.reneefrench.com/][_Renée_French_]]
 
 You can read about the rules of the hackathon
diff --git a/blog/_content/gophergala/fancygopher.jpg b/go.dev/_content/blog/gophergala/fancygopher.jpg
similarity index 100%
rename from blog/_content/gophergala/fancygopher.jpg
rename to go.dev/_content/blog/gophergala/fancygopher.jpg
Binary files differ
diff --git a/blog/_content/gopls-vscode-go.article b/go.dev/_content/blog/gopls-vscode-go.md
similarity index 95%
rename from blog/_content/gopls-vscode-go.article
rename to go.dev/_content/blog/gopls-vscode-go.md
index aebab54..85595e4 100644
--- a/blog/_content/gopls-vscode-go.article
+++ b/go.dev/_content/blog/gopls-vscode-go.md
@@ -1,18 +1,21 @@
-# Gopls on by default in the VS Code Go extension
-01 Feb 2021
-Tags: tools, gopls
-Summary: Gopls, which provides IDE features for Go to many editors, is now used by default in VS Code Go.
+---
+title: Gopls on by default in the VS Code Go extension
+date: 2021-02-01
+by:
+- Go tools team
+tags:
+- tools
+- gopls
+summary: Gopls, which provides IDE features for Go to many editors, is now used by default in VS Code Go.
+---
 
-Go tools team
-
-##
 
 We're happy to announce that the VS Code Go extension now enables the [gopls
 language server](https://github.com/golang/tools/blob/master/gopls/README.md)
 by default, to deliver more robust IDE features and better support for Go
 modules.
 
-.image gopls/features.gif _ 635
+{{image "gopls/features.gif" 635}}
 _(`gopls` provides IDE features, such as as intelligent autocompletion, signature help, refactoring, and workspace symbol search.)_
 
 When [Go modules](using-go-modules) were
diff --git a/blog/_content/gopls/features.gif b/go.dev/_content/blog/gopls/features.gif
similarity index 100%
rename from blog/_content/gopls/features.gif
rename to go.dev/_content/blog/gopls/features.gif
Binary files differ
diff --git a/go.dev/_content/blog/gos-declaration-syntax.md b/go.dev/_content/blog/gos-declaration-syntax.md
new file mode 100644
index 0000000..d18afd2
--- /dev/null
+++ b/go.dev/_content/blog/gos-declaration-syntax.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/declaration-syntax
+---
diff --git a/blog/_content/gothamgo.article b/go.dev/_content/blog/gothamgo.md
similarity index 94%
rename from blog/_content/gothamgo.article
rename to go.dev/_content/blog/gothamgo.md
index 03662e9..973f8b5 100644
--- a/blog/_content/gothamgo.article
+++ b/go.dev/_content/blog/gothamgo.md
@@ -1,11 +1,11 @@
-# GothamGo: gophers in the big apple
-9 Jan 2015
-Summary: Reporting from GothamGo 2015, the first full-day Go conference in New York City.
+---
+title: "GothamGo: gophers in the big apple"
+date: 2015-01-09
+by:
+- Francesc Campoy
+summary: Reporting from GothamGo 2015, the first full-day Go conference in New York City.
+---
 
-Francesc Campoy
-campoy@golang.org
-
-##
 
 Last November more than two hundred gophers from all across the United States
 got together for the first full-day Go conference in New York City.
@@ -14,7 +14,7 @@
 
 And good news, everybody! All the talks were recorded and are available:
 
-.image gothamgo/gothamgo.jpg _ 600
+{{image "gothamgo/gothamgo.jpg" 600}}
 
   - [Launching into Go](http://vimeo.com/115728346) _by Kathy Spardlin_ -
     a CockroachDB contributor provides pointers for people getting started with Go.
diff --git a/blog/_content/gothamgo/gothamgo.jpg b/go.dev/_content/blog/gothamgo/gothamgo.jpg
similarity index 100%
rename from blog/_content/gothamgo/gothamgo.jpg
rename to go.dev/_content/blog/gothamgo/gothamgo.jpg
Binary files differ
diff --git a/blog/_content/gouk15.article b/go.dev/_content/blog/gouk15.md
similarity index 92%
rename from blog/_content/gouk15.article
rename to go.dev/_content/blog/gouk15.md
index ad2d2d0..8aa6519 100644
--- a/blog/_content/gouk15.article
+++ b/go.dev/_content/blog/gouk15.md
@@ -1,17 +1,20 @@
-# Golang UK 2015
-9 Oct 2015
-Tags: conference, golanguk
-Summary: Reporting from GolangUK 2015, the first London Go conference.
+---
+title: Golang UK 2015
+date: 2015-10-09
+by:
+- Francesc Campoy
+tags:
+- conference
+- golanguk
+summary: Reporting from GolangUK 2015, the first London Go conference.
+---
 
-Francesc Campoy
-
-##
 
 On August 21st the Go community gathered in London for the first edition of
 [Golang UK](https://golanguk.com). The conference featured two parallel
 tracks and nearly 400 gophers attended.
 
-.image gouk15/gouk.jpg 300 583
+{{image "gouk15/gouk.jpg" 583 300}}
 
 The conference started with the opening keynote by [David Calavera](https://twitter.com/calavera)
 called Crossing the Language Chasm ([video](https://www.youtube.com/watch?v=JPVRnEZ4v_w&list=PLDWZ5uzn69ezRJYeWxYNRMYebvf8DerHd))
diff --git a/blog/_content/gouk15/gouk.jpg b/go.dev/_content/blog/gouk15/gouk.jpg
similarity index 100%
rename from blog/_content/gouk15/gouk.jpg
rename to go.dev/_content/blog/gouk15/gouk.jpg
Binary files differ
diff --git a/blog/_content/h2push.article b/go.dev/_content/blog/h2push.md
similarity index 92%
rename from blog/_content/h2push.article
rename to go.dev/_content/blog/h2push.md
index 842681d..1db4a9a 100644
--- a/blog/_content/h2push.article
+++ b/go.dev/_content/blog/h2push.md
@@ -1,11 +1,14 @@
-# HTTP/2 Server Push
-24 Mar 2017
-Tags: http, technical
-Summary: How to use HTTP/2 server push to reduce page load times.
-
-Jaana Burcu Dogan
-
-Tom Bergan
+---
+title: HTTP/2 Server Push
+date: 2017-03-24
+by:
+- Jaana Burcu Dogan
+- Tom Bergan
+tags:
+- http
+- technical
+summary: How to use HTTP/2 server push to reduce page load times.
+---
 
 ## Introduction
 
@@ -25,7 +28,7 @@
 to the initial request. This allows the server to fully utilize an
 otherwise idle network and improve page load times.
 
-.image h2push/serverpush.svg _ 600
+{{image "h2push/serverpush.svg" 600}}
 
 At the protocol level, HTTP/2 server push is driven by `PUSH_PROMISE`
 frames. A `PUSH_PROMISE` describes a request that the server predicts the
@@ -47,7 +50,7 @@
 render the page, the handler can initiate a push if `http.Pusher`
 is available:
 
-.code h2push/pusher.go /START/,/END/
+{{code "h2push/pusher.go" `/START/` `/END/`}}
 
 The Push call creates a synthetic request for `/app.js`,
 synthesizes that request into a `PUSH_PROMISE` frame, then forwards
@@ -57,7 +60,7 @@
 if the response to `/app.js` varies on Accept-Encoding,
 then the `PUSH_PROMISE` should include an Accept-Encoding value:
 
-.code h2push/pusher.go /START1/,/END1/
+{{code "h2push/pusher.go" `/START1/` `/END1/`}}
 
 A fully working example is available at:
 
@@ -67,7 +70,7 @@
 your browser's developer tools should show that `app.js` and
 `style.css` were pushed by the server.
 
-.image h2push/networktimeline.png _ 605
+{{image "h2push/networktimeline.png" 605}}
 
 ## Start Your Pushes Before You Respond
 
diff --git a/blog/_content/h2push/networktimeline.png b/go.dev/_content/blog/h2push/networktimeline.png
similarity index 100%
rename from blog/_content/h2push/networktimeline.png
rename to go.dev/_content/blog/h2push/networktimeline.png
Binary files differ
diff --git a/blog/_content/h2push/pusher.go b/go.dev/_content/blog/h2push/pusher.go
similarity index 100%
rename from blog/_content/h2push/pusher.go
rename to go.dev/_content/blog/h2push/pusher.go
diff --git a/blog/_content/h2push/server/cert.pem b/go.dev/_content/blog/h2push/server/cert.pem
similarity index 100%
rename from blog/_content/h2push/server/cert.pem
rename to go.dev/_content/blog/h2push/server/cert.pem
diff --git a/blog/_content/h2push/server/key.pem b/go.dev/_content/blog/h2push/server/key.pem
similarity index 100%
rename from blog/_content/h2push/server/key.pem
rename to go.dev/_content/blog/h2push/server/key.pem
diff --git a/blog/_content/h2push/server/main.go b/go.dev/_content/blog/h2push/server/main.go
similarity index 100%
rename from blog/_content/h2push/server/main.go
rename to go.dev/_content/blog/h2push/server/main.go
diff --git a/blog/_content/h2push/server/static/app.js b/go.dev/_content/blog/h2push/server/static/app.js
similarity index 100%
rename from blog/_content/h2push/server/static/app.js
rename to go.dev/_content/blog/h2push/server/static/app.js
diff --git a/blog/_content/h2push/server/static/style.css b/go.dev/_content/blog/h2push/server/static/style.css
similarity index 100%
rename from blog/_content/h2push/server/static/style.css
rename to go.dev/_content/blog/h2push/server/static/style.css
diff --git a/blog/_content/h2push/serverpush.svg b/go.dev/_content/blog/h2push/serverpush.svg
similarity index 100%
rename from blog/_content/h2push/serverpush.svg
rename to go.dev/_content/blog/h2push/serverpush.svg
diff --git a/blog/_content/hello-china.article b/go.dev/_content/blog/hello-china.md
similarity index 86%
rename from blog/_content/hello-china.article
rename to go.dev/_content/blog/hello-china.md
index 98b57a9..ce88c87 100644
--- a/blog/_content/hello-china.article
+++ b/go.dev/_content/blog/hello-china.md
@@ -1,11 +1,14 @@
-# Hello, 中国!
-22 Jan 2018
-Tags: community, china
-Summary: The Go home page and binary downloads is now available in China, at https://golang.google.cn.
+---
+title: Hello, 中国!
+date: 2018-01-22
+by:
+- Andrew Bonventre
+tags:
+- community
+- china
+summary: "The Go home page and binary downloads is now available in China, at https://golang.google.cn."
+---
 
-Andrew Bonventre
-
-##
 
 We are thrilled to announce that the content on
 [golang.org](https://golang.org) is now available in mainland China through
diff --git a/blog/_content/hello-world.article b/go.dev/_content/blog/hello-world.md
similarity index 95%
rename from blog/_content/hello-world.article
rename to go.dev/_content/blog/hello-world.md
index c0438ee..a3565f4 100644
--- a/blog/_content/hello-world.article
+++ b/go.dev/_content/blog/hello-world.md
@@ -1,11 +1,11 @@
-# Go: What's New in March 2010
-18 Mar 2010
-Summary: First post!
-OldURL: /go-whats-new-in-march-2010
+---
+title: "Go: What's New in March 2010"
+date: 2010-03-18
+by:
+- Andrew Gerrand
+summary: First post!
+---
 
-Andrew Gerrand
-
-##
 
 Welcome to the official Go Blog. We, the Go team,
 hope to use this blog to keep the world up-to-date on the development of
diff --git a/blog/_content/heroku.article b/go.dev/_content/blog/heroku.md
similarity index 88%
rename from blog/_content/heroku.article
rename to go.dev/_content/blog/heroku.md
index 2aa75c2..6ad0b48 100644
--- a/blog/_content/heroku.article
+++ b/go.dev/_content/blog/heroku.md
@@ -1,14 +1,14 @@
-# Go at Heroku
-21 Apr 2011
-Tags: guest
-Summary: _This week’s blog post is written by_ [_Keith Rarick_](http://xph.us/) _and_ [_Blake Mizerany_](http://itsbonus.heroku.com/), _systems engineers at_ [Heroku](http://www.heroku.com/). _In their own words, they "eat, drink, and sleep distributed systems." Here they discuss their experiences using Go._
-OldURL: /go-at-heroku
+---
+title: Go at Heroku
+date: 2011-04-21
+by:
+- Keith Rarick
+- Blake Mizerany
+tags:
+- guest
+summary: "_This week’s blog post is written by_ [_Keith Rarick_](http://xph.us/) _and_ [_Blake Mizerany_](http://itsbonus.heroku.com/), _systems engineers at_ [Heroku](http://www.heroku.com/). _In their own words, they \"eat, drink, and sleep distributed systems.\" Here they discuss their experiences using Go._"
+---
 
-Keith Rarick
-
-Blake Mizerany
-
-##
 
 _This week’s blog post is written by_ [_Keith Rarick_](http://xph.us/)
 _and_ [_Blake Mizerany_](http://itsbonus.heroku.com/),
diff --git a/blog/_content/http-tracing.article b/go.dev/_content/blog/http-tracing.md
similarity index 91%
rename from blog/_content/http-tracing.article
rename to go.dev/_content/blog/http-tracing.md
index 6d63817..97afdeb 100644
--- a/blog/_content/http-tracing.article
+++ b/go.dev/_content/blog/http-tracing.md
@@ -1,9 +1,13 @@
-# Introducing HTTP Tracing
-4 Oct 2016
-Tags: http, technical
-Summary: How to use Go 1.7's HTTP tracing to understand your client requests.
-
-Jaana Burcu Dogan
+---
+title: Introducing HTTP Tracing
+date: 2016-10-04
+by:
+- Jaana Burcu Dogan
+tags:
+- http
+- technical
+summary: How to use Go 1.7's HTTP tracing to understand your client requests.
+---
 
 ## Introduction
 
@@ -36,7 +40,7 @@
 The tracing is scoped to the request's context and users should
 put a `*httptrace.ClientTrace` to the request context before they start a request.
 
-.code http-tracing/trace.go /START/,/END/
+{{code "http-tracing/trace.go" `/START/` `/END/`}}
 
 During a round trip, `http.DefaultTransport` will invoke each hook
 as an event happens. The program above will print the DNS
@@ -54,7 +58,7 @@
 The program below identifies the current request by using an
 `http.RoundTripper` wrapper.
 
-.code http-tracing/client.go
+{{code "http-tracing/client.go"}}
 
 The program will follow the redirect of google.com to www.google.com and will output:
 
diff --git a/blog/_content/http-tracing/client.go b/go.dev/_content/blog/http-tracing/client.go
similarity index 100%
rename from blog/_content/http-tracing/client.go
rename to go.dev/_content/blog/http-tracing/client.go
diff --git a/blog/_content/http-tracing/trace.go b/go.dev/_content/blog/http-tracing/trace.go
similarity index 100%
rename from blog/_content/http-tracing/trace.go
rename to go.dev/_content/blog/http-tracing/trace.go
diff --git a/blog/_content/image-draw.article b/go.dev/_content/blog/image-draw.md
similarity index 94%
rename from blog/_content/image-draw.article
rename to go.dev/_content/blog/image-draw.md
index aa2f77a..cf3b082 100644
--- a/blog/_content/image-draw.article
+++ b/go.dev/_content/blog/image-draw.md
@@ -1,10 +1,15 @@
-# The Go image/draw package
-29 Sep 2011
-Tags: draw, image, libraries, technical
-Summary: An introduction to image compositing in Go using the image/draw package.
-OldURL: /go-imagedraw-package
-
-Nigel Tao
+---
+title: The Go image/draw package
+date: 2011-09-29
+by:
+- Nigel Tao
+tags:
+- draw
+- image
+- libraries
+- technical
+summary: An introduction to image compositing in Go using the image/draw package.
+---
 
 ## Introduction
 
@@ -59,7 +64,7 @@
 The effective rectangle is also clipped to each image's bounds in their
 respective co-ordinate space.
 
-.image image-draw/20.png
+{{image "image-draw/20.png"}}
 
 The [`DrawMask`](https://golang.org/pkg/image/draw/#DrawMask) function
 takes seven arguments,
@@ -103,7 +108,7 @@
 
 	draw.Draw(m, m.Bounds(), image.Transparent, image.ZP, draw.Src)
 
-.image image-draw/2a.png
+{{image "image-draw/2a.png"}}
 
 ## Copying an Image
 
@@ -121,7 +126,7 @@
 
 To copy the entire source image, use `sr = src.Bounds()`.
 
-.image image-draw/2b.png
+{{image "image-draw/2b.png"}}
 
 ## Scrolling an Image
 
@@ -138,7 +143,7 @@
 	draw.Draw(m, b, m, b.Min.Add(p), draw.Src)
 	dirtyRect := b.Intersect(image.Rect(b.Min.X, b.Max.Y-20, b.Max.X, b.Max.Y))
 
-.image image-draw/2c.png
+{{image "image-draw/2c.png"}}
 
 ## Converting an Image to RGBA
 
@@ -152,12 +157,13 @@
 	m := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
 	draw.Draw(m, m.Bounds(), src, b.Min, draw.Src)
 
-.image image-draw/2d.png
+{{image "image-draw/2d.png"}}
 
 ## Drawing Through a Mask
 
 To draw an image through a circular mask with center `p` and radius `r`:
 
+{{raw `
 	type circle struct {
 	    p image.Point
 	    r int
@@ -180,8 +186,9 @@
 	}
 
 	    draw.DrawMask(dst, dst.Bounds(), src, image.ZP, &circle{p, r}, image.ZP, draw.Over)
+`}}
 
-.image image-draw/2e.png
+{{image "image-draw/2e.png"}}
 
 ## Drawing Font Glyphs
 
@@ -195,7 +202,7 @@
 	mr := theBoundsFor(glyphIndex)
 	draw.DrawMask(dst, mr.Sub(mr.Min).Add(p), src, image.ZP, mask, mr.Min, draw.Over)
 
-.image image-draw/2f.png
+{{image "image-draw/2f.png"}}
 
 ## Performance
 
diff --git a/blog/_content/image-draw/20.png b/go.dev/_content/blog/image-draw/20.png
similarity index 100%
rename from blog/_content/image-draw/20.png
rename to go.dev/_content/blog/image-draw/20.png
Binary files differ
diff --git a/blog/_content/image-draw/2a.png b/go.dev/_content/blog/image-draw/2a.png
similarity index 100%
rename from blog/_content/image-draw/2a.png
rename to go.dev/_content/blog/image-draw/2a.png
Binary files differ
diff --git a/blog/_content/image-draw/2b.png b/go.dev/_content/blog/image-draw/2b.png
similarity index 100%
rename from blog/_content/image-draw/2b.png
rename to go.dev/_content/blog/image-draw/2b.png
Binary files differ
diff --git a/blog/_content/image-draw/2c.png b/go.dev/_content/blog/image-draw/2c.png
similarity index 100%
rename from blog/_content/image-draw/2c.png
rename to go.dev/_content/blog/image-draw/2c.png
Binary files differ
diff --git a/blog/_content/image-draw/2d.png b/go.dev/_content/blog/image-draw/2d.png
similarity index 100%
rename from blog/_content/image-draw/2d.png
rename to go.dev/_content/blog/image-draw/2d.png
Binary files differ
diff --git a/blog/_content/image-draw/2e.png b/go.dev/_content/blog/image-draw/2e.png
similarity index 100%
rename from blog/_content/image-draw/2e.png
rename to go.dev/_content/blog/image-draw/2e.png
Binary files differ
diff --git a/blog/_content/image-draw/2f.png b/go.dev/_content/blog/image-draw/2f.png
similarity index 100%
rename from blog/_content/image-draw/2f.png
rename to go.dev/_content/blog/image-draw/2f.png
Binary files differ
diff --git a/blog/_content/image.article b/go.dev/_content/blog/image.md
similarity index 94%
rename from blog/_content/image.article
rename to go.dev/_content/blog/image.md
index 875d117..3198df7 100644
--- a/blog/_content/image.article
+++ b/go.dev/_content/blog/image.md
@@ -1,10 +1,14 @@
-# The Go image package
-21 Sep 2011
-Tags: image, libraries, technical
-Summary: An introduction to 2-D image processing with the Go image package.
-OldURL: /go-image-package
-
-Nigel Tao
+---
+title: The Go image package
+date: 2011-09-21
+by:
+- Nigel Tao
+tags:
+- image
+- libraries
+- technical
+summary: An introduction to 2-D image processing with the Go image package.
+---
 
 ## Introduction
 
@@ -43,6 +47,7 @@
 mask from a third color,
 in the style of [Porter and Duff's](https://en.wikipedia.org/wiki/Alpha_compositing) classic algebra:
 
+{{raw `
 	dstr, dstg, dstb, dsta := dst.RGBA()
 	srcr, srcg, srcb, srca := src.RGBA()
 	_, _, _, m := mask.RGBA()
@@ -50,6 +55,7 @@
 	// The resultant red value is a blend of dstr and srcr, and ranges in [0, M].
 	// The calculation for green, blue and alpha is similar.
 	dstr = (dstr*(M-m) + srcr*m) / M
+`}}
 
 The last line of that code snippet would have been more complicated if we
 worked with non-alpha-premultiplied colors,
@@ -97,7 +103,7 @@
 	    X, Y int
 	}
 
-.image image/image-package-01.png
+{{image "image/image-package-01.png"}}
 
 	p := image.Point{2, 1}
 
@@ -116,13 +122,13 @@
 but is much easier to type.
 
 A `Rectangle` is inclusive at the top-left and exclusive at the bottom-right.
-For a `Point p` and a `Rectangle r`, `p.In(r)` if and only if `r.Min.X <= p.X && p.X < r.Max.X`,
+For a `Point p` and a `Rectangle r`, `p.In(r)` if and only if {{raw "`r.Min.X <= p.X && p.X < r.Max.X`"}},
 and similarly for `Y`.
 This is analogous to how a slice `s[i0:i1]` is inclusive at the low end
 and exclusive at the high end.
 (Unlike arrays and slices, a `Rectangle` often has a non-zero origin.)
 
-.image image/image-package-02.png
+{{image "image/image-package-02.png"}}
 
 	r := image.Rect(2, 1, 5, 5)
 	// Dx and Dy return a rectangle's width and height.
@@ -131,14 +137,14 @@
 Adding a `Point` to a `Rectangle` translates the `Rectangle`.
 Points and Rectangles are not restricted to be in the bottom-right quadrant.
 
-.image image/image-package-03.png
+{{image "image/image-package-03.png"}}
 
 	r := image.Rect(2, 1, 5, 5).Add(image.Pt(-4, -2))
 	fmt.Println(r.Dx(), r.Dy(), image.Pt(0, 0).In(r)) // prints 3 4 true
 
 Intersecting two Rectangles yields another Rectangle, which may be empty.
 
-.image image/image-package-04.png
+{{image "image/image-package-04.png"}}
 
 	r := image.Rect(0, 0, 4, 3).Intersect(image.Rect(2, 2, 5, 5))
 	// Size returns a rectangle's width and height, as a Point.
@@ -174,12 +180,14 @@
 and that area doesn't necessarily start at (0, 0).
 The correct way to iterate over an `Image` m's pixels looks like:
 
+{{raw `
 	b := m.Bounds()
 	for y := b.Min.Y; y < b.Max.Y; y++ {
 	 for x := b.Min.X; x < b.Max.X; x++ {
 	  doStuffWith(m.At(x, y))
 	 }
 	}
+`}}
 
 `Image` implementations do not have to be based on an in-memory slice of pixel data.
 For example, a [`Uniform`](https://golang.org/pkg/image/#Uniform) is an
@@ -220,7 +228,7 @@
 analogous to how modifying the contents of a sub-slice `s[i0:i1]` will affect
 the contents of the original slice `s`.
 
-.image image/image-package-05.png
+{{image "image/image-package-05.png"}}
 
 	m0 := image.NewRGBA(image.Rect(0, 0, 8, 5))
 	m1 := m0.SubImage(image.Rect(1, 2, 5, 5)).(*image.RGBA)
diff --git a/blog/_content/image/image-package-01.png b/go.dev/_content/blog/image/image-package-01.png
similarity index 100%
rename from blog/_content/image/image-package-01.png
rename to go.dev/_content/blog/image/image-package-01.png
Binary files differ
diff --git a/blog/_content/image/image-package-02.png b/go.dev/_content/blog/image/image-package-02.png
similarity index 100%
rename from blog/_content/image/image-package-02.png
rename to go.dev/_content/blog/image/image-package-02.png
Binary files differ
diff --git a/blog/_content/image/image-package-03.png b/go.dev/_content/blog/image/image-package-03.png
similarity index 100%
rename from blog/_content/image/image-package-03.png
rename to go.dev/_content/blog/image/image-package-03.png
Binary files differ
diff --git a/blog/_content/image/image-package-04.png b/go.dev/_content/blog/image/image-package-04.png
similarity index 100%
rename from blog/_content/image/image-package-04.png
rename to go.dev/_content/blog/image/image-package-04.png
Binary files differ
diff --git a/blog/_content/image/image-package-05.png b/go.dev/_content/blog/image/image-package-05.png
similarity index 100%
rename from blog/_content/image/image-package-05.png
rename to go.dev/_content/blog/image/image-package-05.png
Binary files differ
diff --git a/go.dev/_content/blog/index.md b/go.dev/_content/blog/index.md
new file mode 100644
index 0000000..3100665
--- /dev/null
+++ b/go.dev/_content/blog/index.md
@@ -0,0 +1,22 @@
+---
+title: The Go Blog
+---
+
+<div id="blogindex">
+
+{{range first 5 (newest (pages "/blog/*.md")) -}}
+{{if .date}}
+<p class="blogtitle">
+  <a href="{{.URL}}">{{.title}}</a>, <span class="date">{{.date.Format "2 January 2006"}}</span><br>
+  <span class="author">{{with .by}}{{by .}}<br>{{end}}</span>
+  {{with .Tags}}<span class="tags">{{range .}}{{.}} {{end}}</span>{{end}}
+</p>
+<p class="blogsummary">
+  {{.summary}}
+</p>
+{{end}}
+{{end}}
+
+<p class="blogtitle">
+<a href="/blog/all">More articles...</a>
+</p>
diff --git a/go.dev/_content/blog/introducing-go-playground.md b/go.dev/_content/blog/introducing-go-playground.md
new file mode 100644
index 0000000..5d99bfc
--- /dev/null
+++ b/go.dev/_content/blog/introducing-go-playground.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/playground-intro
+---
diff --git a/blog/_content/introducing-gofix.article b/go.dev/_content/blog/introducing-gofix.md
similarity index 96%
rename from blog/_content/introducing-gofix.article
rename to go.dev/_content/blog/introducing-gofix.md
index f6d5673..ee07078 100644
--- a/blog/_content/introducing-gofix.article
+++ b/go.dev/_content/blog/introducing-gofix.md
@@ -1,11 +1,14 @@
-# Introducing Gofix
-15 Apr 2011
-Tags: gofix, technical
-Summary: How to use go fix to update your code with each new Go release.
+---
+title: Introducing Gofix
+date: 2011-04-15
+by:
+- Russ Cox
+tags:
+- gofix
+- technical
+summary: How to use go fix to update your code with each new Go release.
+---
 
-Russ Cox
-
-##
 
 The next Go release will include significant API changes in several fundamental Go packages.
 Code that [implements an HTTP server handler](http://codereview.appspot.com/4239076),
diff --git a/blog/_content/io2010-faq.article b/go.dev/_content/blog/io2010-faq.md
similarity index 93%
rename from blog/_content/io2010-faq.article
rename to go.dev/_content/blog/io2010-faq.md
index e305fcc..423215c 100644
--- a/blog/_content/io2010-faq.article
+++ b/go.dev/_content/blog/io2010-faq.md
@@ -1,12 +1,13 @@
-# Go at I/O: Frequently Asked Questions
-27 May 2010
-Tags: appengine
-Summary: Q&A about Go from Google I/O 2010.
-OldURL: /go-at-io-frequently-asked-questions
+---
+title: "Go at I/O: Frequently Asked Questions"
+date: 2010-05-27
+by:
+- Andrew Gerrand
+tags:
+- appengine
+summary: Q&A about Go from Google I/O 2010.
+---
 
-Andrew Gerrand
-
-##
 
 Among the high-profile product launches at Google I/O last week,
 our small team gave presentations to packed rooms and met many present and
diff --git a/blog/_content/io2010-preview.article b/go.dev/_content/blog/io2010-preview.md
similarity index 86%
rename from blog/_content/io2010-preview.article
rename to go.dev/_content/blog/io2010-preview.md
index 1ea1300..57497cf 100644
--- a/blog/_content/io2010-preview.article
+++ b/go.dev/_content/blog/io2010-preview.md
@@ -1,11 +1,11 @@
-# Upcoming Google I/O Go Events
-12 May 2010
-Summary: If you will be at Google I/O 2010, be sure to catch up with the Go team at these events.
-OldURL: /upcoming-google-io-go-events
+---
+title: Upcoming Google I/O Go Events
+date: 2010-05-12
+by:
+- Andrew Gerrand
+summary: If you will be at Google I/O 2010, be sure to catch up with the Go team at these events.
+---
 
-Andrew Gerrand
-
-##
 
 [Google I/O 2010](https://googleblog.blogspot.com/2010/01/google-io-2010-now-open-for.html)
 is happening next week at the Moscone Centre in San Francisco.
diff --git a/go.dev/_content/blog/io2010.md b/go.dev/_content/blog/io2010.md
new file mode 100644
index 0000000..61a54c4
--- /dev/null
+++ b/go.dev/_content/blog/io2010.md
@@ -0,0 +1,15 @@
+---
+title: Go Programming session video from Google I/O
+date: 2010-06-06
+by:
+- Andrew Gerrand
+tags:
+- video
+- talk
+summary: A talk by Rob Pike and Russ Cox about Go, from Google I/O 2010.
+---
+
+
+Below is the video of the talk given by Rob Pike and Russ Cox at Google I/O 2010.
+
+{{video "https://www.youtube.com/embed/jgVhBThJdXc"}}
diff --git a/blog/_content/io2011.article b/go.dev/_content/blog/io2011.md
similarity index 85%
rename from blog/_content/io2011.article
rename to go.dev/_content/blog/io2011.md
index a6a356a..668be7b 100644
--- a/blog/_content/io2011.article
+++ b/go.dev/_content/blog/io2011.md
@@ -1,10 +1,15 @@
-# Go at Google I/O 2011: videos
-23 May 2011
-Tags: appengine, gopher, talk, video
-Summary: Two talks about Go from Google I/O 2011.
-OldURL: /go-at-google-io-2011-videos
-
-Andrew Gerrand
+---
+title: "Go at Google I/O 2011: videos"
+date: 2011-05-23
+by:
+- Andrew Gerrand
+tags:
+- appengine
+- gopher
+- talk
+- video
+summary: Two talks about Go from Google I/O 2011.
+---
 
 ## Introduction
 
@@ -21,7 +26,7 @@
 and walk through the development and deployment of [Moustachio](http://moustach-io.appspot.com/),
 the first Go App Engine app.
 
-.iframe //www.youtube.com/embed/-i0hat7pdpk 349 560
+{{video "https://www.youtube.com/embed/-i0hat7pdpk"}}
 
 (See the [presentation slides](https://golang.org/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf).)
 
@@ -32,7 +37,7 @@
 
 Most important, this talk features the debut of the plush gopher.
 
-.image io2011/gopher.jpg
+{{image "io2011/gopher.jpg"}}
 
 For those that didn’t get one at the conference, we hope to make him available for purchase online soon.
 
@@ -50,7 +55,7 @@
 
   - [Camlistore](http://www.camlistore.org), a content addressable storage system.
 
-.iframe //www.youtube.com/embed/7QDVRowyUQA 349 560
+{{video "https://www.youtube.com/embed/7QDVRowyUQA"}}
 
 (See the [presentation slides](https://golang.org/doc/talks/io2011/Real_World_Go.pdf).)
 
diff --git a/blog/_content/io2011/gopher.jpg b/go.dev/_content/blog/io2011/gopher.jpg
similarity index 100%
rename from blog/_content/io2011/gopher.jpg
rename to go.dev/_content/blog/io2011/gopher.jpg
Binary files differ
diff --git a/blog/_content/io2012-videos.article b/go.dev/_content/blog/io2012-videos.md
similarity index 76%
rename from blog/_content/io2012-videos.article
rename to go.dev/_content/blog/io2012-videos.md
index 4183c06..f30cb31 100644
--- a/blog/_content/io2012-videos.article
+++ b/go.dev/_content/blog/io2012-videos.md
@@ -1,10 +1,16 @@
-# Go videos from Google I/O 2012
-2 Jul 2012
-Tags: talk, video, concurrency, appengine, ethos
-Summary: Talks about Go from Google I/O 2012.
-OldURL: /go-videos-from-google-io-2012
-
-Andrew Gerrand
+---
+title: Go videos from Google I/O 2012
+date: 2012-07-02
+by:
+- Andrew Gerrand
+tags:
+- talk
+- video
+- concurrency
+- appengine
+- ethos
+summary: Talks about Go from Google I/O 2012.
+---
 
 ## Introduction
 
@@ -16,22 +22,22 @@
 
 _Concurrency is the key to designing high performance network services. Go's concurrency primitives (goroutines and channels) provide a simple and efficient means of expressing concurrent execution. In this talk we see how tricky concurrency problems can be solved gracefully with simple Go code._
 
-.iframe //www.youtube.com/embed/f6kdp27TYZs 304 540
+{{video "https://www.youtube.com/embed/f6kdp27TYZs"}}
 
 ## Go in production
 
 _Since Go's release in 2009 many companies (besides Google, of course) have used the language to build cool stuff. In this session Gustavo Niemeyer (Canonical), Keith Rarick (Heroku), Evan Shaw (Iron.io), and Patrick Crosby (StatHat) share their first-hand experience using Go in production environments._
 
-.iframe //www.youtube.com/embed/kKQLhGZVN4A 304 540
+{{video "https://www.youtube.com/embed/kKQLhGZVN4A"}}
 
 ## Meet the Go team
 
 _A panel discussion with David Symonds, Robert Griesemer, Rob Pike, Ken Thompson, Andrew Gerrand, and Brad Fitzpatrick._
 
-.iframe //www.youtube.com/embed/sln-gJaURzk 304 540
+{{video "https://www.youtube.com/embed/sln-gJaURzk"}}
 
 **Computing Map Tiles with Go on App Engine** by Chris Broadfoot and Andrew Gerrand
 
 _In this talk we use the Maps API and Go on App Engine to build an app to build custom tile sets for Google Maps. The app demonstrates using Go's suitability for computation in the cloud and App Engine's key scalability features, such as Task Queues and Backends._
 
-.iframe //www.youtube.com/embed/sPagpg0b7no 304 540
+{{video "https://www.youtube.com/embed/sPagpg0b7no"}}
diff --git a/blog/_content/io2013-chat.article b/go.dev/_content/blog/io2013-chat.md
similarity index 96%
rename from blog/_content/io2013-chat.article
rename to go.dev/_content/blog/io2013-chat.md
index 9b031da..b76f073 100644
--- a/blog/_content/io2013-chat.article
+++ b/go.dev/_content/blog/io2013-chat.md
@@ -1,16 +1,16 @@
-# A conversation with the Go team
-6 Jun 2013
-Summary: At Google I/O 2013, several members of the Go team hosted a "Fireside chat."
-OldURL: /a-conversation-with-the-go-team
+---
+title: A conversation with the Go team
+date: 2013-06-06
+summary: At Google I/O 2013, several members of the Go team hosted a "Fireside chat."
+---
 
-##
 
 At Google I/O 2013, several members of the Go team hosted a "Fireside chat."
 Robert Griesemer, Rob Pike, David Symonds, Andrew Gerrand, Ian Lance Taylor,
 Sameer Ajmani, Brad Fitzpatrick, and Nigel Tao took questions from the audience
 and people around the world about various aspects of the Go project.
 
-.iframe //www.youtube.com/embed/p9VUCp98ay4 309 549
+{{video "https://www.youtube.com/embed/p9VUCp98ay4"}}
 
 We also hosted a similar session at I/O last year:
 [_Meet the Go team_](http://www.youtube.com/watch?v=sln-gJaURzk).
diff --git a/blog/_content/io2013-talk-concurrency.article b/go.dev/_content/blog/io2013-talk-concurrency.md
similarity index 79%
rename from blog/_content/io2013-talk-concurrency.article
rename to go.dev/_content/blog/io2013-talk-concurrency.md
index 9815c93..70cd130 100644
--- a/blog/_content/io2013-talk-concurrency.article
+++ b/go.dev/_content/blog/io2013-talk-concurrency.md
@@ -1,12 +1,15 @@
-# Advanced Go Concurrency Patterns
-23 May 2013
-Tags: talk, video, concurrency
-Summary: Watch Sameer Ajmani's talk, “Advanced Go Concurrency Patterns,” from Google I/O 2013.
-OldURL: /advanced-go-concurrency-patterns
+---
+title: Advanced Go Concurrency Patterns
+date: 2013-05-23
+by:
+- Andrew Gerrand
+tags:
+- talk
+- video
+- concurrency
+summary: Watch Sameer Ajmani's talk, “Advanced Go Concurrency Patterns,” from Google I/O 2013.
+---
 
-Andrew Gerrand
-
-##
 
 At Google I/O a year ago Rob Pike presented [_Go Concurrency Patterns_](https://talks.golang.org/2012/concurrency.slide),
 an introduction to Go's concurrency model.
@@ -18,7 +21,7 @@
 cancellation, and more.
 For those who want to take their Go programming to the next level, this is a must-see.
 
-.iframe //www.youtube.com/embed/QDDwwePbDtw?rel=0 309 549
+{{video "https://www.youtube.com/embed/QDDwwePbDtw?rel=0"}}
 
 The slides are [available here](https://talks.golang.org/2013/advconc.slide)
 (use the left and right arrows to navigate).
diff --git a/blog/_content/io2013-talks-cloud.article b/go.dev/_content/blog/io2013-talks-cloud.md
similarity index 83%
rename from blog/_content/io2013-talks-cloud.article
rename to go.dev/_content/blog/io2013-talks-cloud.md
index f214ba8..e7def21 100644
--- a/blog/_content/io2013-talks-cloud.article
+++ b/go.dev/_content/blog/io2013-talks-cloud.md
@@ -1,9 +1,10 @@
-# Go and the Google Cloud Platform
-12 Jun 2013
-Summary: Two talks about using Go with the Google Cloud Platform, from Google I/O 2013.
-OldURL: /go-and-google-cloud-platform
-
-Andrew Gerrand
+---
+title: Go and the Google Cloud Platform
+date: 2013-06-12
+by:
+- Andrew Gerrand
+summary: Two talks about using Go with the Google Cloud Platform, from Google I/O 2013.
+---
 
 ## Introduction
 
@@ -27,7 +28,7 @@
 _Come along to hear how to fully exploit the power of Go on App_
 _Engine and make your web applications the best they can be._
 
-.iframe //www.youtube.com/embed/fc25ihfXhbg 309 549
+{{video "https://www.youtube.com/embed/fc25ihfXhbg"}}
 
 ## All the Ships in the World
 
@@ -41,4 +42,4 @@
 _App Engine, Go, Compute Engine, BigQuery, Cloud Storage,_
 _and WebGL to do massive data visualization._
 
-.iframe //www.youtube.com/embed/MT7cd4M9vzs 309 549
+{{video "https://www.youtube.com/embed/MT7cd4M9vzs"}}
diff --git a/blog/_content/io2014.article b/go.dev/_content/blog/io2014.md
similarity index 92%
rename from blog/_content/io2014.article
rename to go.dev/_content/blog/io2014.md
index 7fb3294..8d1b69d 100644
--- a/blog/_content/io2014.article
+++ b/go.dev/_content/blog/io2014.md
@@ -1,9 +1,14 @@
-# Go at Google I/O and Gopher SummerFest
-6 Oct 2014
-Tags: conference, io, report
-Summary: Reporting from Google I/O 2014 and the GoSF Go SummerFest.
-
-Francesc Campoy
+---
+title: Go at Google I/O and Gopher SummerFest
+date: 2014-10-06
+by:
+- Francesc Campoy
+tags:
+- conference
+- io
+- report
+summary: Reporting from Google I/O 2014 and the GoSF Go SummerFest.
+---
 
 ## Introduction
 
@@ -16,7 +21,7 @@
 
 ## Gopher SummerFest
 
-.image io2014/summerfest.jpg _ 800
+{{image "io2014/summerfest.jpg" 800}}
 
 On the Monday, more than 200 gophers gathered at the Google office in San
 Francisco to hear a series of talks:
@@ -41,7 +46,7 @@
 
 ### The Go booth
 
-.image io2014/booth.jpg _ 800
+{{image "io2014/booth.jpg" 800}}
 
 The Go booth was part of the Developer Sandbox area.
 
@@ -79,7 +84,7 @@
 to anyone through the Google I/O extended brand. You can try it yourself at
 [io2014codelabs.appspot.com](https://io2014codelabs.appspot.com/).
 
-.image io2014/collage.jpg _ 800
+{{image "io2014/collage.jpg" 800}}
 
 ## Conclusion
 
diff --git a/blog/_content/io2014/booth.jpg b/go.dev/_content/blog/io2014/booth.jpg
similarity index 100%
rename from blog/_content/io2014/booth.jpg
rename to go.dev/_content/blog/io2014/booth.jpg
Binary files differ
diff --git a/blog/_content/io2014/collage.jpg b/go.dev/_content/blog/io2014/collage.jpg
similarity index 100%
rename from blog/_content/io2014/collage.jpg
rename to go.dev/_content/blog/io2014/collage.jpg
Binary files differ
diff --git a/blog/_content/io2014/crowd.jpg b/go.dev/_content/blog/io2014/crowd.jpg
similarity index 100%
rename from blog/_content/io2014/crowd.jpg
rename to go.dev/_content/blog/io2014/crowd.jpg
Binary files differ
diff --git a/blog/_content/io2014/summerfest.jpg b/go.dev/_content/blog/io2014/summerfest.jpg
similarity index 100%
rename from blog/_content/io2014/summerfest.jpg
rename to go.dev/_content/blog/io2014/summerfest.jpg
Binary files differ
diff --git a/blog/_content/ismmkeynote.article b/go.dev/_content/blog/ismmkeynote.md
similarity index 91%
rename from blog/_content/ismmkeynote.article
rename to go.dev/_content/blog/ismmkeynote.md
index d660037..4b6946c 100644
--- a/blog/_content/ismmkeynote.article
+++ b/go.dev/_content/blog/ismmkeynote.md
@@ -1,11 +1,11 @@
-# Getting to Go: The Journey of Go's Garbage Collector
-12 Jul 2018
-Summary: A technical talk about the structure and details of the new, low-latency Go garbage collector.
+---
+title: "Getting to Go: The Journey of Go's Garbage Collector"
+date: 2018-07-12
+by:
+- Rick Hudson
+summary: A technical talk about the structure and details of the new, low-latency Go garbage collector.
+---
 
-Rick Hudson
-rlh@golang.org
-
-##
 
 This is the transcript from the keynote I gave at the International Symposium
 on Memory Management (ISMM) on June 18, 2018.
@@ -38,7 +38,7 @@
 
 ## The Transcript
 
-.image ismmkeynote/image63.png
+{{image "ismmkeynote/image63.png"}}
 
 Rick Hudson here.
 
@@ -46,7 +46,7 @@
 I have about 45 or 50 minutes of prepared material and after that we will
 have time for discussion and I'll be around so feel free to come up afterwards.
 
-.image ismmkeynote/image24.png
+{{image "ismmkeynote/image24.png"}}
 
 Before I get started I want to acknowledge some people.
 
@@ -62,11 +62,11 @@
 that she has been producing over the years.
 You will see several of them throughout the talk.
 
-.image ismmkeynote/image38.png
+{{image "ismmkeynote/image38.png"}}
 
 Before we get revved up and going on this stuff we really have to show what GC's view of Go looks like.
 
-.image ismmkeynote/image32.png
+{{image "ismmkeynote/image32.png"}}
 
 Well first of all Go programs have hundreds of thousands of stacks.
 They are managed by the Go scheduler and are always preempted at GC safepoints.
@@ -75,7 +75,7 @@
 We manage the stacks and their size by copying them and updating pointers in the stack.
 It's a local operation so it scales fairly well.
 
-.image ismmkeynote/image22.png
+{{image "ismmkeynote/image22.png"}}
 
 The next thing that is important is the fact that Go is a value-oriented
 language in the tradition of C-like systems languages rather than reference-oriented
@@ -95,12 +95,12 @@
 have to go on with the runtime.
 It is probably the most important thing that differentiates Go from other GCed languages.
 
-.image ismmkeynote/image60.png
+{{image "ismmkeynote/image60.png"}}
 
 Of course Go can have pointers and in fact they can have interior pointers.
 Such pointers keep the entire value live and they are fairly common.
 
-.image ismmkeynote/image29.png
+{{image "ismmkeynote/image29.png"}}
 
 We also have a way ahead of time compilation system so the binary contains the entire runtime.
 
@@ -112,7 +112,7 @@
 
 So there are pluses and minuses.
 
-.image ismmkeynote/image13.png
+{{image "ismmkeynote/image13.png"}}
 
 Go comes with two knobs to control the GC.
 The first one is GCPercent. Basically this is a knob that adjusts how much
@@ -135,11 +135,11 @@
 
 This wraps up our discussion on the pieces of Go that are important to the garbage collector.
 
-.image ismmkeynote/image3.png
+{{image "ismmkeynote/image3.png"}}
 
 So now let's talk about the Go runtime and how did we get here, how we got to where we are.
 
-.image ismmkeynote/image59.png
+{{image "ismmkeynote/image59.png"}}
 
 So it's 2014. If Go does not solve this GC latency problem somehow then
 Go isn't going to be successful. That was clear.
@@ -150,7 +150,7 @@
 
 Why is latency so important?
 
-.image ismmkeynote/image7.png
+{{image "ismmkeynote/image7.png"}}
 
 The math is completely unforgiving on this.
 
@@ -175,7 +175,7 @@
 
 We call this problem the tyranny of the 9s.
 
-.image ismmkeynote/image36.png
+{{image "ismmkeynote/image36.png"}}
 
 So how do you fight the tyranny of the 9s?
 
@@ -192,7 +192,7 @@
 but they didn't tackle the root problem of GC latency.
 At Google scale we had to tackle the root problem. Why?
 
-.image ismmkeynote/image48.png
+{{image "ismmkeynote/image48.png"}}
 
 Redundancy wasn't going to scale, redundancy costs a lot. It costs new server farms.
 
@@ -201,7 +201,7 @@
 fields and give some kernel of corn the chance to be knee high by the fourth
 of July and reach its full potential.
 
-.image ismmkeynote/image56.png
+{{image "ismmkeynote/image56.png"}}
 
 So here is the 2014 SLO. Yes, it was true that I was sandbagging,
 I was new on the team, it was a new process to me,
@@ -209,7 +209,7 @@
 
 Furthermore presentations about GC latency in other languages were just plain scary.
 
-.image ismmkeynote/image67.png
+{{image "ismmkeynote/image67.png"}}
 
 The original plan was to do a read barrier free concurrent copying GC.
 That was the long term plan. There was a lot of uncertainty about the overhead
@@ -227,7 +227,7 @@
 But that was it. We couldn't slow down Go programs.
 That would have been untenable in 2014.
 
-.image ismmkeynote/image28.png
+{{image "ismmkeynote/image28.png"}}
 
 So we backed off a bit. We weren't going to do the copying part.
 
@@ -243,7 +243,7 @@
 would be minimally impacted and the compiler team could move forward rapidly.
 Go also desperately needed short term success in 2015.
 
-.image ismmkeynote/image55.png
+{{image "ismmkeynote/image55.png"}}
 
 So let's look at some of the things we did.
 
@@ -273,7 +273,7 @@
 to pin objects and put levels of indirection between C and the Go object
 you are working with.
 
-.image ismmkeynote/image5.png
+{{image "ismmkeynote/image5.png"}}
 
 The next design choice was where to put the object's metadata.
 We needed to have some information about the objects since we didn't have headers.
@@ -286,7 +286,7 @@
 or to do other debugging things.
 This was really valuable for getting this stuff running and finding bugs.
 
-.image ismmkeynote/image19.png
+{{image "ismmkeynote/image19.png"}}
 
 So what about write barriers? The write barrier is on only during the GC.
 At other times the compiled code loads a global variable and looks at it.
@@ -296,7 +296,7 @@
 and the write barrier is responsible for ensuring that no reachable objects
 get lost during the tri-color operations.
 
-.image ismmkeynote/image50.png
+{{image "ismmkeynote/image50.png"}}
 
 The other piece of this code is the GC Pacer.
 It is some of the great work that Austin did.
@@ -326,12 +326,12 @@
 [\*Go 1.5 concurrent garbage collector pacing](https://golang.org/s/go15gcpacing)
 and [Proposal: Separate soft and hard heap size goal](https://github.com/golang/proposal/blob/master/design/14951-soft-heap-limit.md)
 
-.image ismmkeynote/image40.png
+{{image "ismmkeynote/image40.png"}}
 
 Yes, so we had successes, lots of them. A younger crazier Rick would have
 taken some of these graphs and tattooed them on my shoulder I was so proud of them.
 
-.image ismmkeynote/image20.png
+{{image "ismmkeynote/image20.png"}}
 
 This is a series of graphs that was done for a production server at Twitter.
 We of course had nothing to do with that production server.
@@ -347,13 +347,13 @@
 
 We are going to change the Y-axis here radically from 0 to 400 milliseconds down to 0 to 50 milliseconds.
 
-.image ismmkeynote/image54.png
+{{image "ismmkeynote/image54.png"}}
 
 This is 6 months later. The improvement was largely due to systematically
 eliminating all the O(heap) things we were doing during the stop the world time.
 This was our second order of magnitude improvement as we went from 40 milliseconds down to 4 or 5.
 
-.image ismmkeynote/image1.png
+{{image "ismmkeynote/image1.png"}}
 
 There were some bugs in there that we had to clean up and we did this during
 a minor release 1.6.3.
@@ -361,7 +361,7 @@
 
 We are about to change our Y-axis again, this time down to 0 to 5 milliseconds.
 
-.image ismmkeynote/image68.png
+{{image "ismmkeynote/image68.png"}}
 
 So here we are, this is August of 2016, a year after the first release.
 Again we kept knocking off these O(heap size) stop the world processes.
@@ -370,7 +370,7 @@
 the size of the heap could obviously grow considerable without impacting latency.
 So this was a bit of a help in 1.7.
 
-.image ismmkeynote/image58.png
+{{image "ismmkeynote/image58.png"}}
 
 The next release was in March of 2017. We had the last of our large latency
 drops which was due to figuring out how to avoid the stop the world stack
@@ -379,7 +379,7 @@
 Again the Y axis is about to change to 1.5 milliseconds and we see our third
 order of magnitude improvement.
 
-.image ismmkeynote/image45.png
+{{image "ismmkeynote/image45.png"}}
 
 The August 2017 release saw little improvement.
 We know what is causing the remaining pauses.
@@ -394,7 +394,7 @@
 
 There was no substantial change in the Feb'18 1.10 release just some clean-up and chasing corner cases.
 
-.image ismmkeynote/image6.png
+{{image "ismmkeynote/image6.png"}}
 
 So a new year and a new SLO This is our 2018 SLO.
 
@@ -411,17 +411,17 @@
 We were pretty happy with this. Again this is not an SLA but an SLO so it's an objective,
 not an agreement, since we can't control such things as the OS.
 
-.image ismmkeynote/image64.png
+{{image "ismmkeynote/image64.png"}}
 
 That's the good stuff. Let's shift and start talking about our failures.
 These are our scars; they are sort of like tattoos and everyone gets them.
 Anyway they come with better stories so let's do some of those stories.
 
-.image ismmkeynote/image46.png
+{{image "ismmkeynote/image46.png"}}
 
 Our first attempt was to do something called the request oriented collector or ROC. The hypothesis can be seen here.
 
-.image ismmkeynote/image34.png
+{{image "ismmkeynote/image34.png"}}
 
 So what does this mean?
 
@@ -431,23 +431,23 @@
 They have their own private stacks and their own selection of private objects.
 Say the guy on the left wants to share the green object.
 
-.image ismmkeynote/image9.png
+{{image "ismmkeynote/image9.png"}}
 
 The goroutine puts it in the shared area so the other Goroutine can access it.
 They can hook it to something in the shared heap or assign it to a global
 variable and the other Goroutine can see it.
 
-.image ismmkeynote/image26.png
+{{image "ismmkeynote/image26.png"}}
 
 Finally the Goroutine on the left goes to its death bed, it's about to die, sad.
 
-.image ismmkeynote/image14.png
+{{image "ismmkeynote/image14.png"}}
 
 As you know you can't take your objects with you when you die.
 You can't take your stack either. The stack is actually empty at this time
 and the objects are unreachable so you can simply reclaim them.
 
-.image ismmkeynote/image2.png
+{{image "ismmkeynote/image2.png"}}
 
 The important thing here is that all actions were local and did not require
 any global synchronization.
@@ -455,7 +455,7 @@
 and the hope was that the scaling we would get from not having to do that
 synchronization would be sufficient for us to have a win.
 
-.image ismmkeynote/image27.png
+{{image "ismmkeynote/image27.png"}}
 
 The other issue that was going on with this system was that the write barrier was always on.
 Whenever there was a write, we would have to see if it was writing a pointer
@@ -464,7 +464,7 @@
 walk of reachable objects making sure they were also public.
 That was a pretty expensive write barrier that could cause many cache misses.
 
-.image ismmkeynote/image30.png
+{{image "ismmkeynote/image30.png"}}
 
 That said, wow, we had some pretty good successes.
 
@@ -477,7 +477,7 @@
 things actually scale quite nicely.
 If you don't have ROC on it wasn't nearly as good.
 
-.image ismmkeynote/image35.png
+{{image "ismmkeynote/image35.png"}}
 
 But that wasn't good enough, we also had to make sure that ROC didn't slow
 down other pieces of the system.
@@ -488,7 +488,7 @@
 Go is proud of how fast its compiler is so we couldn't slow the compiler down,
 certainly not this much.
 
-.image ismmkeynote/image61.png
+{{image "ismmkeynote/image61.png"}}
 
 We then went and looked at some other programs.
 These are our performance benchmarks. We have a corpus of 200 or 300 benchmarks
@@ -497,7 +497,7 @@
 These weren't selected by the GC folks at all.
 The numbers were uniformly bad and ROC wasn't going to become a winner.
 
-.image ismmkeynote/image44.png
+{{image "ismmkeynote/image44.png"}}
 
 It's true we scaled but we only had 4 to 12 hardware thread system so we
 couldn't overcome the write barrier tax.
@@ -506,19 +506,19 @@
 When that happens we might come back and revisit this,
 but for now ROC was a losing proposition.
 
-.image ismmkeynote/image66.png
+{{image "ismmkeynote/image66.png"}}
 
 So what were we going to do next? Let's try the generational GC.
 It's an oldie but a goodie. ROC didn't work so let's go back to stuff we
 have a lot more experience with.
 
-.image ismmkeynote/image41.png
+{{image "ismmkeynote/image41.png"}}
 
 We weren't going to give up our latency, we weren't going to give up the
 fact that we were non-moving.
 So we needed a non-moving generational GC.
 
-.image ismmkeynote/image27.png
+{{image "ismmkeynote/image27.png"}}
 
 So could we do this? Yes, but with a generational GC,
 the write barrier is always on.
@@ -526,38 +526,38 @@
 but when GC is off we use a fast GC write barrier that buffers the pointers
 and then flushes the buffer to a card mark table when it overflows.
 
-.image ismmkeynote/image4.png
+{{image "ismmkeynote/image4.png"}}
 
 So how is this going to work in a non-moving situation? Here is the mark / allocation map.
 Basically you maintain a current pointer.
 When you are allocating you look for the next zero and when you find that
 zero you allocate an object in that space.
 
-.image ismmkeynote/image51.png
+{{image "ismmkeynote/image51.png"}}
 
 You then update the current pointer to the next 0.
 
-.image ismmkeynote/image17.png
+{{image "ismmkeynote/image17.png"}}
 
 You continue until at some point it is time to do a generation GC.
 You will notice that if there is a one in the mark/allocation vector then
 that object was alive at the last GC so it is mature.
 If it is zero and you reach it then you know it is young.
 
-.image ismmkeynote/image53.png
+{{image "ismmkeynote/image53.png"}}
 
 So how do you do promoting. If you find something marked with a 1 pointing
 to something marked with a 0 then you promote the referent simply by setting that zero to a one.
 
-.image ismmkeynote/image49.png
+{{image "ismmkeynote/image49.png"}}
 
 You have to do a transitive walk to make sure all reachable objects are promoted.
 
-.image ismmkeynote/image69.png
+{{image "ismmkeynote/image69.png"}}
 
 When all reachable objects have been promoted the minor GC terminates.
 
-.image ismmkeynote/image62.png
+{{image "ismmkeynote/image62.png"}}
 
 Finally, to finish your generational GC cycle you simply set the current
 pointer back to the start of the vector and you can continue.
@@ -565,16 +565,16 @@
 As many of you know this is called 'sticky bits' and was invented by Hans
 Boehm and his colleagues.
 
-.image ismmkeynote/image21.png
+{{image "ismmkeynote/image21.png"}}
 
 So what did the performance look like? It wasn't bad for the large heaps.
 These were the benchmarks that the GC should do well on. This was all good.
 
-.image ismmkeynote/image65.png
+{{image "ismmkeynote/image65.png"}}
 
 We then ran it on our performance benchmarks and things didn't go as well. So what was going on?
 
-.image ismmkeynote/image43.png
+{{image "ismmkeynote/image43.png"}}
 
 The write barrier was fast but it simply wasn't fast enough.
 Furthermore it was hard to optimize for. For example,
@@ -583,7 +583,7 @@
 But we were having to move to a system where we have a GC safepoint at every
 instruction so there really wasn't any write barrier that we could elide going forward.
 
-.image ismmkeynote/image47.png
+{{image "ismmkeynote/image47.png"}}
 
 We also had escape analysis and it was getting better and better.
 Remember the value-oriented stuff we were talking about? Instead of passing
@@ -598,7 +598,7 @@
 The result is that generational collection is much less effective than you
 might find in other managed runtime languages.
 
-.image ismmkeynote/image10.png
+{{image "ismmkeynote/image10.png"}}
 
 So these forces against the write barrier were starting to gather.
 Today, our compiler is much better than it was in 2014.
@@ -614,7 +614,7 @@
 
 But that's not the main compelling reason why write barriers in Go have an uphill fight going forward.
 
-.image ismmkeynote/image8.png
+{{image "ismmkeynote/image8.png"}}
 
 Let's look at this graph. It's just an analytical graph of mark costs.
 Each line represents a different application that might have a mark cost.
@@ -626,7 +626,7 @@
 The write barrier costs are constant so the cost of increasing the heap
 size will drive that marking cost underneath the cost of the write barrier.
 
-.image ismmkeynote/image39.png
+{{image "ismmkeynote/image39.png"}}
 
 Here is a more common cost for a write barrier,
 which is 4%, and we see that even with that we can drive the cost of the
@@ -640,7 +640,7 @@
 Go doesn't have this stop the world problem so it had to look more closely
 at the throughput problems and that is what we did.
 
-.image ismmkeynote/image23.png
+{{image "ismmkeynote/image23.png"}}
 
 That's a lot of failure and with such failure comes food and lunch.
 I'm doing my usual whining "Gee wouldn't this be great if it wasn't for the write barrier."
@@ -657,7 +657,7 @@
 
 Anyway that got us talking, what about something crazy?
 
-.image ismmkeynote/image25.png
+{{image "ismmkeynote/image25.png"}}
 
 What about card marking without a write barrier? It turns out that Austin
 has these files and he writes into these files all of his crazy ideas that
@@ -672,7 +672,7 @@
 be considered marked.
 This would trade the cost of write barrier off for cost of hashing.
 
-.image ismmkeynote/image31.png
+{{image "ismmkeynote/image31.png"}}
 
 But more importantly it's hardware aligned.
 
@@ -690,11 +690,11 @@
 to run C, and to run the SPECint benchmarks.
 It's no surprise that the result is hardware that runs this kind of stuff fast.
 
-.image ismmkeynote/image12.png
+{{image "ismmkeynote/image12.png"}}
 
 We took the measurement. This is pretty good. This is the benchmark suite for large heaps which should be good.
 
-.image ismmkeynote/image18.png
+{{image "ismmkeynote/image18.png"}}
 
 We then said what does it look like for the performance benchmark? Not so good,
 a couple of outliers.
@@ -709,11 +709,11 @@
 But is this going to win going forward? We have to know or at least think
 about what hardware is going to look like going forward.
 
-.image ismmkeynote/image52.png
+{{image "ismmkeynote/image52.png"}}
 
 What are the memories of the future?
 
-.image ismmkeynote/image11.png
+{{image "ismmkeynote/image11.png"}}
 
 Let's take a look at this graph. This is your classic Moore's law graph.
 You have a log scale on the Y axis showing the number of transistors in a single chip.
@@ -742,7 +742,7 @@
 [Original graph](http://www.kurzweilai.net/ask-ray-the-future-of-moores-law)
 at www.kurzweilai.net/ask-ray-the-future-of-moores-law.
 
-.image ismmkeynote/image57.png
+{{image "ismmkeynote/image57.png"}}
 
 Let's look at another graph focused on DRAM.
 These are numbers from a recent PhD thesis from CMU.
@@ -774,7 +774,7 @@
 The original graph in the introduction was not in a form that I could draw
 a Moore's law line on it easily so I changed the X-axis to be more uniform.)
 
-.image ismmkeynote/image15.png
+{{image "ismmkeynote/image15.png"}}
 
 Let's go to where the rubber meets the road.
 This is actual DRAM pricing and it has generally declined from 2005 to 2016.
@@ -798,7 +798,7 @@
 
 (Sources [https://hblok.net/blog/](https://hblok.net/blog/) and [https://hblok.net/storage\_data/storage\_memory\_prices\_2005-2017-12.png](https://hblok.net/storage_data/storage_memory_prices_2005-2017-12.png))
 
-.image ismmkeynote/image37.png
+{{image "ismmkeynote/image37.png"}}
 
 Let's look at this other line. Gee it would be nice if we were on this line.
 This is the SSD line. It is doing a better job of keeping prices low.
@@ -817,11 +817,11 @@
 
 All of this reinforces our decision to avoid always-on barriers in favor of increasing memory.
 
-.image ismmkeynote/image16.png
+{{image "ismmkeynote/image16.png"}}
 
 So what does all this mean for Go going forward?
 
-.image ismmkeynote/image42.png
+{{image "ismmkeynote/image42.png"}}
 
 We intend to make the runtime more flexible and robust as we look at corner
 cases that come in from our users.
@@ -845,7 +845,7 @@
 
 So that's it. Thank you.
 
-.image ismmkeynote/image33.png
+{{image "ismmkeynote/image33.png"}}
 
 P.S. The Go team is looking to hire engineers to help develop and maintain the Go runtime and compiler toolchain.
 
diff --git a/blog/_content/ismmkeynote/image1.png b/go.dev/_content/blog/ismmkeynote/image1.png
similarity index 100%
rename from blog/_content/ismmkeynote/image1.png
rename to go.dev/_content/blog/ismmkeynote/image1.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image10.png b/go.dev/_content/blog/ismmkeynote/image10.png
similarity index 100%
rename from blog/_content/ismmkeynote/image10.png
rename to go.dev/_content/blog/ismmkeynote/image10.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image11.png b/go.dev/_content/blog/ismmkeynote/image11.png
similarity index 100%
rename from blog/_content/ismmkeynote/image11.png
rename to go.dev/_content/blog/ismmkeynote/image11.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image12.png b/go.dev/_content/blog/ismmkeynote/image12.png
similarity index 100%
rename from blog/_content/ismmkeynote/image12.png
rename to go.dev/_content/blog/ismmkeynote/image12.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image13.png b/go.dev/_content/blog/ismmkeynote/image13.png
similarity index 100%
rename from blog/_content/ismmkeynote/image13.png
rename to go.dev/_content/blog/ismmkeynote/image13.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image14.png b/go.dev/_content/blog/ismmkeynote/image14.png
similarity index 100%
rename from blog/_content/ismmkeynote/image14.png
rename to go.dev/_content/blog/ismmkeynote/image14.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image15.png b/go.dev/_content/blog/ismmkeynote/image15.png
similarity index 100%
rename from blog/_content/ismmkeynote/image15.png
rename to go.dev/_content/blog/ismmkeynote/image15.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image16.png b/go.dev/_content/blog/ismmkeynote/image16.png
similarity index 100%
rename from blog/_content/ismmkeynote/image16.png
rename to go.dev/_content/blog/ismmkeynote/image16.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image17.png b/go.dev/_content/blog/ismmkeynote/image17.png
similarity index 100%
rename from blog/_content/ismmkeynote/image17.png
rename to go.dev/_content/blog/ismmkeynote/image17.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image18.png b/go.dev/_content/blog/ismmkeynote/image18.png
similarity index 100%
rename from blog/_content/ismmkeynote/image18.png
rename to go.dev/_content/blog/ismmkeynote/image18.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image19.png b/go.dev/_content/blog/ismmkeynote/image19.png
similarity index 100%
rename from blog/_content/ismmkeynote/image19.png
rename to go.dev/_content/blog/ismmkeynote/image19.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image2.png b/go.dev/_content/blog/ismmkeynote/image2.png
similarity index 100%
rename from blog/_content/ismmkeynote/image2.png
rename to go.dev/_content/blog/ismmkeynote/image2.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image20.png b/go.dev/_content/blog/ismmkeynote/image20.png
similarity index 100%
rename from blog/_content/ismmkeynote/image20.png
rename to go.dev/_content/blog/ismmkeynote/image20.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image21.png b/go.dev/_content/blog/ismmkeynote/image21.png
similarity index 100%
rename from blog/_content/ismmkeynote/image21.png
rename to go.dev/_content/blog/ismmkeynote/image21.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image22.png b/go.dev/_content/blog/ismmkeynote/image22.png
similarity index 100%
rename from blog/_content/ismmkeynote/image22.png
rename to go.dev/_content/blog/ismmkeynote/image22.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image23.png b/go.dev/_content/blog/ismmkeynote/image23.png
similarity index 100%
rename from blog/_content/ismmkeynote/image23.png
rename to go.dev/_content/blog/ismmkeynote/image23.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image24.png b/go.dev/_content/blog/ismmkeynote/image24.png
similarity index 100%
rename from blog/_content/ismmkeynote/image24.png
rename to go.dev/_content/blog/ismmkeynote/image24.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image25.png b/go.dev/_content/blog/ismmkeynote/image25.png
similarity index 100%
rename from blog/_content/ismmkeynote/image25.png
rename to go.dev/_content/blog/ismmkeynote/image25.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image26.png b/go.dev/_content/blog/ismmkeynote/image26.png
similarity index 100%
rename from blog/_content/ismmkeynote/image26.png
rename to go.dev/_content/blog/ismmkeynote/image26.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image27.png b/go.dev/_content/blog/ismmkeynote/image27.png
similarity index 100%
rename from blog/_content/ismmkeynote/image27.png
rename to go.dev/_content/blog/ismmkeynote/image27.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image28.png b/go.dev/_content/blog/ismmkeynote/image28.png
similarity index 100%
rename from blog/_content/ismmkeynote/image28.png
rename to go.dev/_content/blog/ismmkeynote/image28.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image29.png b/go.dev/_content/blog/ismmkeynote/image29.png
similarity index 100%
rename from blog/_content/ismmkeynote/image29.png
rename to go.dev/_content/blog/ismmkeynote/image29.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image3.png b/go.dev/_content/blog/ismmkeynote/image3.png
similarity index 100%
rename from blog/_content/ismmkeynote/image3.png
rename to go.dev/_content/blog/ismmkeynote/image3.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image30.png b/go.dev/_content/blog/ismmkeynote/image30.png
similarity index 100%
rename from blog/_content/ismmkeynote/image30.png
rename to go.dev/_content/blog/ismmkeynote/image30.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image31.png b/go.dev/_content/blog/ismmkeynote/image31.png
similarity index 100%
rename from blog/_content/ismmkeynote/image31.png
rename to go.dev/_content/blog/ismmkeynote/image31.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image32.png b/go.dev/_content/blog/ismmkeynote/image32.png
similarity index 100%
rename from blog/_content/ismmkeynote/image32.png
rename to go.dev/_content/blog/ismmkeynote/image32.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image33.png b/go.dev/_content/blog/ismmkeynote/image33.png
similarity index 100%
rename from blog/_content/ismmkeynote/image33.png
rename to go.dev/_content/blog/ismmkeynote/image33.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image34.png b/go.dev/_content/blog/ismmkeynote/image34.png
similarity index 100%
rename from blog/_content/ismmkeynote/image34.png
rename to go.dev/_content/blog/ismmkeynote/image34.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image35.png b/go.dev/_content/blog/ismmkeynote/image35.png
similarity index 100%
rename from blog/_content/ismmkeynote/image35.png
rename to go.dev/_content/blog/ismmkeynote/image35.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image36.png b/go.dev/_content/blog/ismmkeynote/image36.png
similarity index 100%
rename from blog/_content/ismmkeynote/image36.png
rename to go.dev/_content/blog/ismmkeynote/image36.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image37.png b/go.dev/_content/blog/ismmkeynote/image37.png
similarity index 100%
rename from blog/_content/ismmkeynote/image37.png
rename to go.dev/_content/blog/ismmkeynote/image37.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image38.png b/go.dev/_content/blog/ismmkeynote/image38.png
similarity index 100%
rename from blog/_content/ismmkeynote/image38.png
rename to go.dev/_content/blog/ismmkeynote/image38.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image39.png b/go.dev/_content/blog/ismmkeynote/image39.png
similarity index 100%
rename from blog/_content/ismmkeynote/image39.png
rename to go.dev/_content/blog/ismmkeynote/image39.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image4.png b/go.dev/_content/blog/ismmkeynote/image4.png
similarity index 100%
rename from blog/_content/ismmkeynote/image4.png
rename to go.dev/_content/blog/ismmkeynote/image4.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image40.png b/go.dev/_content/blog/ismmkeynote/image40.png
similarity index 100%
rename from blog/_content/ismmkeynote/image40.png
rename to go.dev/_content/blog/ismmkeynote/image40.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image41.png b/go.dev/_content/blog/ismmkeynote/image41.png
similarity index 100%
rename from blog/_content/ismmkeynote/image41.png
rename to go.dev/_content/blog/ismmkeynote/image41.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image42.png b/go.dev/_content/blog/ismmkeynote/image42.png
similarity index 100%
rename from blog/_content/ismmkeynote/image42.png
rename to go.dev/_content/blog/ismmkeynote/image42.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image43.png b/go.dev/_content/blog/ismmkeynote/image43.png
similarity index 100%
rename from blog/_content/ismmkeynote/image43.png
rename to go.dev/_content/blog/ismmkeynote/image43.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image44.png b/go.dev/_content/blog/ismmkeynote/image44.png
similarity index 100%
rename from blog/_content/ismmkeynote/image44.png
rename to go.dev/_content/blog/ismmkeynote/image44.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image45.png b/go.dev/_content/blog/ismmkeynote/image45.png
similarity index 100%
rename from blog/_content/ismmkeynote/image45.png
rename to go.dev/_content/blog/ismmkeynote/image45.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image46.png b/go.dev/_content/blog/ismmkeynote/image46.png
similarity index 100%
rename from blog/_content/ismmkeynote/image46.png
rename to go.dev/_content/blog/ismmkeynote/image46.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image47.png b/go.dev/_content/blog/ismmkeynote/image47.png
similarity index 100%
rename from blog/_content/ismmkeynote/image47.png
rename to go.dev/_content/blog/ismmkeynote/image47.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image48.png b/go.dev/_content/blog/ismmkeynote/image48.png
similarity index 100%
rename from blog/_content/ismmkeynote/image48.png
rename to go.dev/_content/blog/ismmkeynote/image48.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image49.png b/go.dev/_content/blog/ismmkeynote/image49.png
similarity index 100%
rename from blog/_content/ismmkeynote/image49.png
rename to go.dev/_content/blog/ismmkeynote/image49.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image5.png b/go.dev/_content/blog/ismmkeynote/image5.png
similarity index 100%
rename from blog/_content/ismmkeynote/image5.png
rename to go.dev/_content/blog/ismmkeynote/image5.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image50.png b/go.dev/_content/blog/ismmkeynote/image50.png
similarity index 100%
rename from blog/_content/ismmkeynote/image50.png
rename to go.dev/_content/blog/ismmkeynote/image50.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image51.png b/go.dev/_content/blog/ismmkeynote/image51.png
similarity index 100%
rename from blog/_content/ismmkeynote/image51.png
rename to go.dev/_content/blog/ismmkeynote/image51.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image52.png b/go.dev/_content/blog/ismmkeynote/image52.png
similarity index 100%
rename from blog/_content/ismmkeynote/image52.png
rename to go.dev/_content/blog/ismmkeynote/image52.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image53.png b/go.dev/_content/blog/ismmkeynote/image53.png
similarity index 100%
rename from blog/_content/ismmkeynote/image53.png
rename to go.dev/_content/blog/ismmkeynote/image53.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image54.png b/go.dev/_content/blog/ismmkeynote/image54.png
similarity index 100%
rename from blog/_content/ismmkeynote/image54.png
rename to go.dev/_content/blog/ismmkeynote/image54.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image55.png b/go.dev/_content/blog/ismmkeynote/image55.png
similarity index 100%
rename from blog/_content/ismmkeynote/image55.png
rename to go.dev/_content/blog/ismmkeynote/image55.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image56.png b/go.dev/_content/blog/ismmkeynote/image56.png
similarity index 100%
rename from blog/_content/ismmkeynote/image56.png
rename to go.dev/_content/blog/ismmkeynote/image56.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image57.png b/go.dev/_content/blog/ismmkeynote/image57.png
similarity index 100%
rename from blog/_content/ismmkeynote/image57.png
rename to go.dev/_content/blog/ismmkeynote/image57.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image58.png b/go.dev/_content/blog/ismmkeynote/image58.png
similarity index 100%
rename from blog/_content/ismmkeynote/image58.png
rename to go.dev/_content/blog/ismmkeynote/image58.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image59.png b/go.dev/_content/blog/ismmkeynote/image59.png
similarity index 100%
rename from blog/_content/ismmkeynote/image59.png
rename to go.dev/_content/blog/ismmkeynote/image59.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image6.png b/go.dev/_content/blog/ismmkeynote/image6.png
similarity index 100%
rename from blog/_content/ismmkeynote/image6.png
rename to go.dev/_content/blog/ismmkeynote/image6.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image60.png b/go.dev/_content/blog/ismmkeynote/image60.png
similarity index 100%
rename from blog/_content/ismmkeynote/image60.png
rename to go.dev/_content/blog/ismmkeynote/image60.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image61.png b/go.dev/_content/blog/ismmkeynote/image61.png
similarity index 100%
rename from blog/_content/ismmkeynote/image61.png
rename to go.dev/_content/blog/ismmkeynote/image61.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image62.png b/go.dev/_content/blog/ismmkeynote/image62.png
similarity index 100%
rename from blog/_content/ismmkeynote/image62.png
rename to go.dev/_content/blog/ismmkeynote/image62.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image63.png b/go.dev/_content/blog/ismmkeynote/image63.png
similarity index 100%
rename from blog/_content/ismmkeynote/image63.png
rename to go.dev/_content/blog/ismmkeynote/image63.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image64.png b/go.dev/_content/blog/ismmkeynote/image64.png
similarity index 100%
rename from blog/_content/ismmkeynote/image64.png
rename to go.dev/_content/blog/ismmkeynote/image64.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image65.png b/go.dev/_content/blog/ismmkeynote/image65.png
similarity index 100%
rename from blog/_content/ismmkeynote/image65.png
rename to go.dev/_content/blog/ismmkeynote/image65.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image66.png b/go.dev/_content/blog/ismmkeynote/image66.png
similarity index 100%
rename from blog/_content/ismmkeynote/image66.png
rename to go.dev/_content/blog/ismmkeynote/image66.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image67.png b/go.dev/_content/blog/ismmkeynote/image67.png
similarity index 100%
rename from blog/_content/ismmkeynote/image67.png
rename to go.dev/_content/blog/ismmkeynote/image67.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image68.png b/go.dev/_content/blog/ismmkeynote/image68.png
similarity index 100%
rename from blog/_content/ismmkeynote/image68.png
rename to go.dev/_content/blog/ismmkeynote/image68.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image69.png b/go.dev/_content/blog/ismmkeynote/image69.png
similarity index 100%
rename from blog/_content/ismmkeynote/image69.png
rename to go.dev/_content/blog/ismmkeynote/image69.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image7.png b/go.dev/_content/blog/ismmkeynote/image7.png
similarity index 100%
rename from blog/_content/ismmkeynote/image7.png
rename to go.dev/_content/blog/ismmkeynote/image7.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image8.png b/go.dev/_content/blog/ismmkeynote/image8.png
similarity index 100%
rename from blog/_content/ismmkeynote/image8.png
rename to go.dev/_content/blog/ismmkeynote/image8.png
Binary files differ
diff --git a/blog/_content/ismmkeynote/image9.png b/go.dev/_content/blog/ismmkeynote/image9.png
similarity index 100%
rename from blog/_content/ismmkeynote/image9.png
rename to go.dev/_content/blog/ismmkeynote/image9.png
Binary files differ
diff --git a/go.dev/_content/blog/json-and-go.md b/go.dev/_content/blog/json-and-go.md
new file mode 100644
index 0000000..2ef4374
--- /dev/null
+++ b/go.dev/_content/blog/json-and-go.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/json
+---
diff --git a/go.dev/_content/blog/json-rpc-tale-of-interfaces.md b/go.dev/_content/blog/json-rpc-tale-of-interfaces.md
new file mode 100644
index 0000000..e140cf8
--- /dev/null
+++ b/go.dev/_content/blog/json-rpc-tale-of-interfaces.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/json-rpc
+---
diff --git a/blog/_content/json-rpc.article b/go.dev/_content/blog/json-rpc.md
similarity index 91%
rename from blog/_content/json-rpc.article
rename to go.dev/_content/blog/json-rpc.md
index fc0541f..7355172 100644
--- a/blog/_content/json-rpc.article
+++ b/go.dev/_content/blog/json-rpc.md
@@ -1,12 +1,15 @@
-# JSON-RPC: a tale of interfaces
-27 Apr 2010
-Tags: json, rpc, technical
-Summary: How to use the net/rpc package's interfaces to create a JSON-RPC system.
-OldURL: /json-rpc-tale-of-interfaces
+---
+title: "JSON-RPC: a tale of interfaces"
+date: 2010-04-27
+by:
+- Andrew Gerrand
+tags:
+- json
+- rpc
+- technical
+summary: How to use the net/rpc package's interfaces to create a JSON-RPC system.
+---
 
-Andrew Gerrand
-
-##
 
 Here we present an example where Go's [interfaces](https://golang.org/doc/effective_go.html#interfaces_and_types)
 made it easy to refactor some existing code to make it more flexible and extensible.
diff --git a/blog/_content/json.article b/go.dev/_content/blog/json.md
similarity index 97%
rename from blog/_content/json.article
rename to go.dev/_content/blog/json.md
index d6a1c9b..5710795 100644
--- a/blog/_content/json.article
+++ b/go.dev/_content/blog/json.md
@@ -1,10 +1,13 @@
-# JSON and Go
-25 Jan 2011
-Tags: json, technical
-Summary: How to generate and consume JSON-formatted data in Go.
-OldURL: /json-and-go
-
-Andrew Gerrand
+---
+title: JSON and Go
+date: 2011-01-25
+by:
+- Andrew Gerrand
+tags:
+- json
+- technical
+summary: How to generate and consume JSON-formatted data in Go.
+---
 
 ## Introduction
 
diff --git a/blog/_content/laws-of-reflection.article b/go.dev/_content/blog/laws-of-reflection.md
similarity index 97%
rename from blog/_content/laws-of-reflection.article
rename to go.dev/_content/blog/laws-of-reflection.md
index 0cf8b55..4f7748f 100644
--- a/blog/_content/laws-of-reflection.article
+++ b/go.dev/_content/blog/laws-of-reflection.md
@@ -1,9 +1,15 @@
-# The Laws of Reflection
-6 Sep 2011
-Tags: interface, reflect, type, technical
-Summary: How reflections works in Go, how to think about it, and how to use it.
-
-Rob Pike
+---
+title: The Laws of Reflection
+date: 2011-09-06
+by:
+- Rob Pike
+tags:
+- interface
+- reflect
+- type
+- technical
+summary: How reflections works in Go, how to think about it, and how to use it.
+---
 
 ## Introduction
 
@@ -195,7 +201,9 @@
 
 prints
 
+{{raw `
 	value: <float64 Value>
+`}}
 
 (We call the `String` method explicitly because by default the `fmt` package
 digs into a `reflect.Value` to show the concrete value inside.
@@ -431,6 +439,7 @@
 Note that we extract the names of the fields from the struct type,
 but the fields themselves are regular `reflect.Value` objects.
 
+{{raw `
 	type T struct {
 	    A int
 	    B string
@@ -443,6 +452,7 @@
 	    fmt.Printf("%d: %s %s = %v\n", i,
 	        typeOfT.Field(i).Name, f.Type(), f.Interface())
 	}
+`}}
 
 The output of this program is
 
diff --git a/go.dev/_content/blog/learn-go-from-your-browser.md b/go.dev/_content/blog/learn-go-from-your-browser.md
new file mode 100644
index 0000000..332e15e
--- /dev/null
+++ b/go.dev/_content/blog/learn-go-from-your-browser.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/tour
+---
diff --git a/blog/_content/maps.article b/go.dev/_content/blog/maps.md
similarity index 95%
rename from blog/_content/maps.article
rename to go.dev/_content/blog/maps.md
index e7b054e..6aad79a 100644
--- a/blog/_content/maps.article
+++ b/go.dev/_content/blog/maps.md
@@ -1,10 +1,13 @@
-# Go maps in action
-6 Feb 2013
-Tags: map, technical
-Summary: How and when to use Go maps.
-OldURL: /go-maps-in-action
-
-Andrew Gerrand
+---
+title: Go maps in action
+date: 2013-02-06
+by:
+- Andrew Gerrand
+tags:
+- map
+- technical
+summary: How and when to use Go maps.
+---
 
 ## Introduction
 
@@ -110,7 +113,7 @@
 This example traverses a linked list of `Nodes` and prints their values.
 It uses a map of `Node` pointers to detect cycles in the list.
 
-.code maps/list.go /START/,/END/
+{{code "maps/list.go" `/START/` `/END/`}}
 
 The expression `visited[n]` is `true` if `n` has been visited,
 or `false` if `n` is not present.
@@ -125,15 +128,15 @@
 Each `Person` has a `Name` and a slice of Likes.
 The example creates a map to associate each like with a slice of people that like it.
 
-.code maps/people.go /START1/,/END1/
+{{code "maps/people.go" `/START1/` `/END1/`}}
 
 To print a list of people who like cheese:
 
-.code maps/people.go /START2/,/END2/
+{{code "maps/people.go" `/START2/` `/END2/`}}
 
 To print the number of people who like bacon:
 
-.code maps/people.go /bacon/
+{{code "maps/people.go" `/bacon/`}}
 
 Note that since both range and len treat a nil slice as a zero-length slice,
 these last two examples will work even if nobody likes cheese or bacon (however
diff --git a/blog/_content/maps/list.go b/go.dev/_content/blog/maps/list.go
similarity index 100%
rename from blog/_content/maps/list.go
rename to go.dev/_content/blog/maps/list.go
diff --git a/blog/_content/maps/people.go b/go.dev/_content/blog/maps/people.go
similarity index 100%
rename from blog/_content/maps/people.go
rename to go.dev/_content/blog/maps/people.go
diff --git a/blog/_content/matchlang.article b/go.dev/_content/blog/matchlang.md
similarity index 96%
rename from blog/_content/matchlang.article
rename to go.dev/_content/blog/matchlang.md
index 70c121a..86ffe4b 100644
--- a/blog/_content/matchlang.article
+++ b/go.dev/_content/blog/matchlang.md
@@ -1,9 +1,17 @@
-# Language and Locale Matching in Go
-9 Feb 2016
-Tags: language, locale, tag, BCP 47, matching
-Summary: How to internationalize your web site with Go's language and locale matching.
-
-Marcel van Lohuizen
+---
+title: Language and Locale Matching in Go
+date: 2016-02-09
+by:
+- Marcel van Lohuizen
+tags:
+- language
+- locale
+- tag
+- BCP
+- 47
+- matching
+summary: How to internationalize your web site with Go's language and locale matching.
+---
 
 ## Introduction
 
@@ -24,7 +32,7 @@
 Here are some examples of BCP 47 language tags and the language or dialect they
 represent.
 
-.html matchlang/tags.html
+{{raw (file "matchlang/tags.html")}}
 
 The general form of the language tag is
 a language code (“en”, “cmn”, “zh”, “nl”, “az” above)
@@ -137,7 +145,7 @@
 Here is a sample program, explained below, matching a user's language
 preferences against an application's supported languages:
 
-.code -edit matchlang/complete.go
+{{code "matchlang/complete.go"}}
 
 ### Creating Language Tags
 
@@ -273,7 +281,7 @@
 
 For example:
 
-.code -edit matchlang/display.go /START/,/END/
+{{code "matchlang/display.go" `/START/` `/END/`}}
 
 prints
 
diff --git a/blog/_content/matchlang/complete.go b/go.dev/_content/blog/matchlang/complete.go
similarity index 100%
rename from blog/_content/matchlang/complete.go
rename to go.dev/_content/blog/matchlang/complete.go
diff --git a/blog/_content/matchlang/display.go b/go.dev/_content/blog/matchlang/display.go
similarity index 100%
rename from blog/_content/matchlang/display.go
rename to go.dev/_content/blog/matchlang/display.go
diff --git a/blog/_content/matchlang/tags.html b/go.dev/_content/blog/matchlang/tags.html
similarity index 100%
rename from blog/_content/matchlang/tags.html
rename to go.dev/_content/blog/matchlang/tags.html
diff --git a/blog/_content/meetups.article b/go.dev/_content/blog/meetups.md
similarity index 89%
rename from blog/_content/meetups.article
rename to go.dev/_content/blog/meetups.md
index ba1e0e8..6dccbdf 100644
--- a/blog/_content/meetups.article
+++ b/go.dev/_content/blog/meetups.md
@@ -1,12 +1,14 @@
-# Get thee to a Go meetup
-27 Feb 2013
-Tags: community, talk
-Summary: How to find or start a local group of gophers.
-OldURL: /getthee-to-go-meetup
+---
+title: Get thee to a Go meetup
+date: 2013-02-27
+by:
+- Andrew Gerrand
+tags:
+- community
+- talk
+summary: How to find or start a local group of gophers.
+---
 
-Andrew Gerrand
-
-##
 
 Last week, David Symonds and I each gave talks at Sydney's Go meetup,
 [golang-syd](http://www.meetup.com/golang-syd/).
diff --git a/blog/_content/migrating-to-go-modules.article b/go.dev/_content/blog/migrating-to-go-modules.md
similarity index 97%
rename from blog/_content/migrating-to-go-modules.article
rename to go.dev/_content/blog/migrating-to-go-modules.md
index 000553d..da586ba 100644
--- a/blog/_content/migrating-to-go-modules.article
+++ b/go.dev/_content/blog/migrating-to-go-modules.md
@@ -1,9 +1,14 @@
-# Migrating to Go Modules
-21 Aug 2019
-Tags: tools, versioning, modules
-Summary: How to use Go modules to manage your program's dependencies.
-
-Jean de Klerk
+---
+title: Migrating to Go Modules
+date: 2019-08-21
+by:
+- Jean de Klerk
+tags:
+- tools
+- versioning
+- modules
+summary: How to use Go modules to manage your program's dependencies.
+---
 
 ## Introduction
 
diff --git a/blog/_content/module-compatibility.article b/go.dev/_content/blog/module-compatibility.md
similarity index 97%
rename from blog/_content/module-compatibility.article
rename to go.dev/_content/blog/module-compatibility.md
index 1f0362d..4ace6a1 100644
--- a/blog/_content/module-compatibility.article
+++ b/go.dev/_content/blog/module-compatibility.md
@@ -1,11 +1,14 @@
-# Keeping Your Modules Compatible
-7 Jul 2020
-Tags: tools, versioning
-Summary: How to keep your modules compatible with prior minor/patch versions.
-
-Jean de Klerk
-
-Jonathan Amsterdam
+---
+title: Keeping Your Modules Compatible
+date: 2020-07-07
+by:
+- Jean de Klerk
+- Jonathan Amsterdam
+tags:
+- tools
+- versioning
+summary: How to keep your modules compatible with prior minor/patch versions.
+---
 
 ## Introduction
 
diff --git a/blog/_content/module-mirror-launch.article b/go.dev/_content/blog/module-mirror-launch.md
similarity index 94%
rename from blog/_content/module-mirror-launch.article
rename to go.dev/_content/blog/module-mirror-launch.md
index f1cf3dd..4fac424 100644
--- a/blog/_content/module-mirror-launch.article
+++ b/go.dev/_content/blog/module-mirror-launch.md
@@ -1,11 +1,14 @@
-# Module Mirror and Checksum Database Launched
-29 Aug 2019
-Tags: tools, versioning
-Summary: The Go module mirror and checksum database provide faster, verified downloads of your Go dependencies.
+---
+title: Module Mirror and Checksum Database Launched
+date: 2019-08-29
+by:
+- Katie Hockman
+tags:
+- tools
+- versioning
+summary: The Go module mirror and checksum database provide faster, verified downloads of your Go dependencies.
+---
 
-Katie Hockman
-
-##
 
 We are excited to share that our module [mirror](https://proxy.golang.org),
 [index](https://index.golang.org), and
@@ -46,7 +49,7 @@
 an example of how the `go` command may use a proxy with `go get` by requesting the list
 of versions, then the info, mod, and zip file for the latest tagged version.
 
-.image module-mirror-launch/proxy-protocol.png _ 800
+{{image "module-mirror-launch/proxy-protocol.png" 800}}
 
 A module mirror is a special kind of module proxy that caches metadata and
 source code in its own storage system, allowing the mirror to continue to serve
@@ -93,7 +96,7 @@
 proofs (that the tree hasn’t been tampered with) before adding new `go.sum` lines
 to your module’s `go.sum` file. Below is an example of such a tree.
 
-.image module-mirror-launch/tree.png _ 800
+{{image "module-mirror-launch/tree.png" 800}}
 
 The checksum database supports
 [a set of endpoints](https://go.googlesource.com/proposal/+/master/design/25530-sumdb.md#checksum-database)
@@ -104,7 +107,7 @@
 interact with the checksum database by doing a `/lookup` of a module version, then
 requesting the tiles required for the proofs.
 
-.image module-mirror-launch/sumdb-protocol.png _ 800
+{{image "module-mirror-launch/sumdb-protocol.png" 800}}
 
 This checksum database allows the `go` command to safely use an otherwise
 untrusted proxy. Because there is an auditable security layer sitting on top of
diff --git a/blog/_content/module-mirror-launch/proxy-protocol.png b/go.dev/_content/blog/module-mirror-launch/proxy-protocol.png
similarity index 100%
rename from blog/_content/module-mirror-launch/proxy-protocol.png
rename to go.dev/_content/blog/module-mirror-launch/proxy-protocol.png
Binary files differ
diff --git a/blog/_content/module-mirror-launch/sumdb-protocol.png b/go.dev/_content/blog/module-mirror-launch/sumdb-protocol.png
similarity index 100%
rename from blog/_content/module-mirror-launch/sumdb-protocol.png
rename to go.dev/_content/blog/module-mirror-launch/sumdb-protocol.png
Binary files differ
diff --git a/blog/_content/module-mirror-launch/tree.png b/go.dev/_content/blog/module-mirror-launch/tree.png
similarity index 100%
rename from blog/_content/module-mirror-launch/tree.png
rename to go.dev/_content/blog/module-mirror-launch/tree.png
Binary files differ
diff --git a/blog/_content/modules2019.article b/go.dev/_content/blog/modules2019.md
similarity index 97%
rename from blog/_content/modules2019.article
rename to go.dev/_content/blog/modules2019.md
index f077037..4ee352b 100644
--- a/blog/_content/modules2019.article
+++ b/go.dev/_content/blog/modules2019.md
@@ -1,9 +1,13 @@
-# Go Modules in 2019
-19 Dec 2018
-Tags: tools, versioning
-Summary: What the Go team is planning for Go modules in 2019.
-
-Russ Cox
+---
+title: Go Modules in 2019
+date: 2018-12-19
+by:
+- Russ Cox
+tags:
+- tools
+- versioning
+summary: What the Go team is planning for Go modules in 2019.
+---
 
 ## What a year!
 
@@ -225,7 +229,7 @@
 This diagram shows how module source code
 moves through the design in this post.
 
-.image modules2019/code.png _ 374
+{{image "modules2019/code.png" 374}}
 
 Before, all consumers of Go source code—the `go` command
 and any sites like godoc.org—fetched code directly from each code host.
diff --git a/blog/_content/modules2019/code.graffle b/go.dev/_content/blog/modules2019/code.graffle
similarity index 100%
rename from blog/_content/modules2019/code.graffle
rename to go.dev/_content/blog/modules2019/code.graffle
Binary files differ
diff --git a/blog/_content/modules2019/code.png b/go.dev/_content/blog/modules2019/code.png
similarity index 100%
rename from blog/_content/modules2019/code.png
rename to go.dev/_content/blog/modules2019/code.png
Binary files differ
diff --git a/blog/_content/new-talk-and-tutorials.article b/go.dev/_content/blog/new-talk-and-tutorials.md
similarity index 87%
rename from blog/_content/new-talk-and-tutorials.article
rename to go.dev/_content/blog/new-talk-and-tutorials.md
index 4df0c47..efb459c 100644
--- a/blog/_content/new-talk-and-tutorials.article
+++ b/go.dev/_content/blog/new-talk-and-tutorials.md
@@ -1,10 +1,11 @@
-# New Talk and Tutorials
-5 May 2010
-Summary: More materials for learning about Go: one talk, one codelab, and one screencast.
+---
+title: New Talk and Tutorials
+date: 2010-05-05
+by:
+- Andrew Gerrand
+summary: "More materials for learning about Go: one talk, one codelab, and one screencast."
+---
 
-Andrew Gerrand
-
-##
 
 Rob Pike recently gave a talk at Stanford's [Computer Systems Colloquium](http://www.stanford.edu/class/ee380/) (EE380).
 Titled [_Another Go at Language Design_](http://www.stanford.edu/class/ee380/Abstracts/100428.html),
diff --git a/blog/_content/normalization.article b/go.dev/_content/blog/normalization.md
similarity index 96%
rename from blog/_content/normalization.article
rename to go.dev/_content/blog/normalization.md
index e984148..aff5705 100644
--- a/blog/_content/normalization.article
+++ b/go.dev/_content/blog/normalization.md
@@ -1,9 +1,15 @@
-# Text normalization in Go
-26 Nov 2013
-Tags: strings, bytes, runes, characters
-Summary: How and why to normalize UTF-8 text in Go.
-
-Marcel van Lohuizen
+---
+title: Text normalization in Go
+date: 2013-11-26
+by:
+- Marcel van Lohuizen
+tags:
+- strings
+- bytes
+- runes
+- characters
+summary: How and why to normalize UTF-8 text in Go.
+---
 
 ## Introduction
 
@@ -45,7 +51,7 @@
 This table shows the names, all starting with NF, by which the Unicode
 Consortium identifies these forms:
 
-.html normalization/table1.html
+{{raw (file "normalization/table1.html")}}
 
 ## Go's approach to normalization
 
@@ -257,7 +263,7 @@
 and NFC and can in every case be returned as is. The second sample is neither
 and requires writing a new version.
 
-.html normalization/table2.html
+{{raw (file "normalization/table2.html")}}
 
 The column with the results for the iterator shows both the measurement with
 and without initialization of the iterator, which contain buffers that don't
diff --git a/blog/_content/normalization/table1.html b/go.dev/_content/blog/normalization/table1.html
similarity index 100%
rename from blog/_content/normalization/table1.html
rename to go.dev/_content/blog/normalization/table1.html
diff --git a/blog/_content/normalization/table2.html b/go.dev/_content/blog/normalization/table2.html
similarity index 100%
rename from blog/_content/normalization/table2.html
rename to go.dev/_content/blog/normalization/table2.html
diff --git a/blog/_content/open-source.article b/go.dev/_content/blog/open-source.md
similarity index 98%
rename from blog/_content/open-source.article
rename to go.dev/_content/blog/open-source.md
index 90c2596..66d1495 100644
--- a/blog/_content/open-source.article
+++ b/go.dev/_content/blog/open-source.md
@@ -1,9 +1,12 @@
-# Go, Open Source, Community
-8 Jul 2015
-Tags: community
-Summary: Why is Go open source, and how can we strengthen our open-source community?
-
-Russ Cox
+---
+title: Go, Open Source, Community
+date: 2015-07-08
+by:
+- Russ Cox
+tags:
+- community
+summary: Why is Go open source, and how can we strengthen our open-source community?
+---
 
 ## Welcome
 
diff --git a/blog/_content/organizing-go-code.article b/go.dev/_content/blog/organizing-go-code.md
similarity index 95%
rename from blog/_content/organizing-go-code.article
rename to go.dev/_content/blog/organizing-go-code.md
index 13ea8f5..c46e73d 100644
--- a/blog/_content/organizing-go-code.article
+++ b/go.dev/_content/blog/organizing-go-code.md
@@ -1,9 +1,17 @@
-# Organizing Go code
-16 Aug 2012
-Tags: godoc, gopath, interface, libraries, tools, technical
-Summary: How to name and package the parts of your Go program to best serve your users.
-
-Andrew Gerrand
+---
+title: Organizing Go code
+date: 2012-08-16
+by:
+- Andrew Gerrand
+tags:
+- godoc
+- gopath
+- interface
+- libraries
+- tools
+- technical
+summary: How to name and package the parts of your Go program to best serve your users.
+---
 
 ## Introduction
 
diff --git a/blog/_content/oscon.article b/go.dev/_content/blog/oscon.md
similarity index 91%
rename from blog/_content/oscon.article
rename to go.dev/_content/blog/oscon.md
index c91d55c..ef2f50b 100644
--- a/blog/_content/oscon.article
+++ b/go.dev/_content/blog/oscon.md
@@ -1,11 +1,14 @@
-# Go will be at OSCON 2014
-15 Jul 2014
-Tags: conference, oscon
-Summary: If you will be at OSCON 2014, July 20-29 in Portland, Oregon, be sure to check out these Go talks.
+---
+title: Go will be at OSCON 2014
+date: 2014-07-15
+by:
+- Francesc Campoy
+tags:
+- conference
+- oscon
+summary: If you will be at OSCON 2014, July 20-29 in Portland, Oregon, be sure to check out these Go talks.
+---
 
-Francesc Campoy
-
-##
 
 [OSCON](http://www.oscon.com), the Open Source Convention, is taking place
 from July 20th to the 29th in Portland, Oregon and Go will be central to many
diff --git a/blog/_content/osconreport.article b/go.dev/_content/blog/osconreport.md
similarity index 90%
rename from blog/_content/osconreport.article
rename to go.dev/_content/blog/osconreport.md
index 356b722..650dab7 100644
--- a/blog/_content/osconreport.article
+++ b/go.dev/_content/blog/osconreport.md
@@ -1,9 +1,13 @@
-# Go at OSCON
-20 Aug 2014
-Tags: conference, oscon
-Summary: Reporting from OSCON 2014.
-
-Francesc Campoy
+---
+title: Go at OSCON
+date: 2014-08-20
+by:
+- Francesc Campoy
+tags:
+- conference
+- oscon
+summary: Reporting from OSCON 2014.
+---
 
 ## Introduction
 
@@ -24,7 +28,7 @@
 [Go for Object Oriented Programmers](http://spf13.com/presentation/go-for-object-oriented-programmers),
 where he explained how some object oriented concepts can be implemented in Go.
 
-.image osconreport/talks.png _ 800
+{{image "osconreport/talks.png" 800}}
 
 Finally, [Josh Bleecher Snyder](http://twitter.com/offbymany) talked about his
 experience writing tools to work with Go source code in
@@ -40,7 +44,7 @@
 [Getting started with Go](http://spf13.com/presentation/first-go-app) to a big
 room full of Gophers.
 
-.image osconreport/workshops.png _ 800
+{{image "osconreport/workshops.png" 800}}
 
 In the afternoon, [Chris McEniry](https://twitter.com/mmceniry) gave his
 [Quick introduction to system tools programming with Go](http://cdn.oreillystatic.com/en/assets/1/event/115/A%20Quick%20Introduction%20to%20System%20Tools%20Programming%20with%20Go%20Presentation.pdf) where he went over some useful skills to
@@ -53,7 +57,7 @@
 meetup and a
 [Birds of a Feather session](http://www.oscon.com/oscon2014/public/schedule/detail/37775).
 
-.image osconreport/meetup.png _ 800
+{{image "osconreport/meetup.png" 800}}
 
 At the meetup Francesc Campoy talked about
 [Go Best Practices](https://talks.golang.org/2013/bestpractices.slide) and
@@ -68,7 +72,7 @@
 
 ## In conclusion
 
-.image osconreport/random.png _ 800
+{{image "osconreport/random.png" 800}}
 
 Thanks to all the gophers that participated in OSCON. After the successes of
 this year we look forward to more Go fun at OSCON 2015.
diff --git a/blog/_content/osconreport/meetup.png b/go.dev/_content/blog/osconreport/meetup.png
similarity index 100%
rename from blog/_content/osconreport/meetup.png
rename to go.dev/_content/blog/osconreport/meetup.png
Binary files differ
diff --git a/blog/_content/osconreport/random.png b/go.dev/_content/blog/osconreport/random.png
similarity index 100%
rename from blog/_content/osconreport/random.png
rename to go.dev/_content/blog/osconreport/random.png
Binary files differ
diff --git a/blog/_content/osconreport/talks.png b/go.dev/_content/blog/osconreport/talks.png
similarity index 100%
rename from blog/_content/osconreport/talks.png
rename to go.dev/_content/blog/osconreport/talks.png
Binary files differ
diff --git a/blog/_content/osconreport/workshops.png b/go.dev/_content/blog/osconreport/workshops.png
similarity index 100%
rename from blog/_content/osconreport/workshops.png
rename to go.dev/_content/blog/osconreport/workshops.png
Binary files differ
diff --git a/blog/_content/package-names.article b/go.dev/_content/blog/package-names.md
similarity index 97%
rename from blog/_content/package-names.article
rename to go.dev/_content/blog/package-names.md
index b28b73e..4cd2735 100644
--- a/blog/_content/package-names.article
+++ b/go.dev/_content/blog/package-names.md
@@ -1,9 +1,14 @@
-# Package names
-4 Feb 2015
-Tags: package, names, style
-Summary: How to name your packages.
-
-Sameer Ajmani
+---
+title: Package names
+date: 2015-02-04
+by:
+- Sameer Ajmani
+tags:
+- package
+- names
+- style
+summary: How to name your packages.
+---
 
 ## Introduction
 
diff --git a/blog/_content/pandemic.article b/go.dev/_content/blog/pandemic.md
similarity index 96%
rename from blog/_content/pandemic.article
rename to go.dev/_content/blog/pandemic.md
index c08a86b..4683679 100644
--- a/blog/_content/pandemic.article
+++ b/go.dev/_content/blog/pandemic.md
@@ -1,14 +1,13 @@
-# Go, the Go Community, and the Pandemic
-25 Mar 2020
-Summary: How the Go team is approaching the pandemic, what you can expect from us, and what you can do.
+---
+title: Go, the Go Community, and the Pandemic
+date: 2020-03-25
+by:
+- Carmen Andoh
+- Russ Cox
+- Steve Francia
+summary: How the Go team is approaching the pandemic, what you can expect from us, and what you can do.
+---
 
-Carmen Andoh
-
-Russ Cox
-
-Steve Francia
-
-##
 
 Go always comes second to more
 basic concerns like personal and family health and safety.
diff --git a/blog/_content/path-security.article b/go.dev/_content/blog/path-security.md
similarity index 97%
rename from blog/_content/path-security.article
rename to go.dev/_content/blog/path-security.md
index 196b45c..ac76ed2 100644
--- a/blog/_content/path-security.article
+++ b/go.dev/_content/blog/path-security.md
@@ -1,10 +1,11 @@
-# Command PATH security in Go
-19 Jan 2021
-Summary: How to decide if your programs are vulnerable to PATH problems, and what to do about it.
+---
+title: Command PATH security in Go
+date: 2021-01-19
+by:
+- Russ Cox
+summary: How to decide if your programs are vulnerable to PATH problems, and what to do about it.
+---
 
-Russ Cox
-
-##
 
 Today’s [Go security release](https://golang.org/s/go-security-release-jan-2021)
 fixes an issue involving PATH lookups in untrusted directories
diff --git a/blog/_content/pipelines.article b/go.dev/_content/blog/pipelines.md
similarity index 88%
rename from blog/_content/pipelines.article
rename to go.dev/_content/blog/pipelines.md
index c898135..7f16629 100644
--- a/blog/_content/pipelines.article
+++ b/go.dev/_content/blog/pipelines.md
@@ -1,9 +1,14 @@
-# Go Concurrency Patterns: Pipelines and cancellation
-13 Mar 2014
-Tags: concurrency, pipelines, cancellation
-Summary: How to use Go's concurrency to build data-processing pipelines.
-
-Sameer Ajmani
+---
+title: "Go Concurrency Patterns: Pipelines and cancellation"
+date: 2014-03-13
+by:
+- Sameer Ajmani
+tags:
+- concurrency
+- pipelines
+- cancellation
+summary: How to use Go's concurrency to build data-processing pipelines.
+---
 
 ## Introduction
 
@@ -40,25 +45,25 @@
 goroutine that sends the integers on the channel and closes the channel when all
 the values have been sent:
 
-.code pipelines/square.go /func gen/,/^}/
+{{code "pipelines/square.go" `/func gen/` `/^}/`}}
 
 The second stage, `sq`, receives integers from a channel and returns a
 channel that emits the square of each received integer.  After the
 inbound channel is closed and this stage has sent all the values
 downstream, it closes the outbound channel:
 
-.code pipelines/square.go /func sq/,/^}/
+{{code "pipelines/square.go" `/func sq/` `/^}/`}}
 
 The `main` function sets up the pipeline and runs the final stage: it receives
 values from the second stage and prints each one, until the channel is closed:
 
-.code pipelines/square.go /func main/,/^}/
+{{code "pipelines/square.go" `/func main/` `/^}/`}}
 
 Since `sq` has the same type for its inbound and outbound channels, we
 can compose it any number of times.  We can also rewrite `main` as a
 range loop, like the other stages:
 
-.code pipelines/square2.go /func main/,/^}/
+{{code "pipelines/square2.go" `/func main/` `/^}/`}}
 
 ## Fan-out, fan-in
 
@@ -74,7 +79,7 @@
 same input channel.  We introduce a new function, _merge_, to fan in the
 results:
 
-.code pipelines/sqfan.go /func main/,/^}/
+{{code "pipelines/sqfan.go" `/func main/` `/^}/`}}
 
 The `merge` function converts a list of channels to a single channel by starting
 a goroutine for each inbound channel that copies the values to the sole outbound
@@ -87,7 +92,7 @@
 [`sync.WaitGroup`](https://golang.org/pkg/sync/#WaitGroup) type
 provides a simple way to arrange this synchronization:
 
-.code pipelines/sqfan.go /func merge/,/^}/
+{{code "pipelines/sqfan.go" `/func merge/` `/^}/`}}
 
 ## Stopping short
 
@@ -111,7 +116,7 @@
 In our example pipeline, if a stage fails to consume all the inbound values, the
 goroutines attempting to send those values will block indefinitely:
 
-.code pipelines/sqleak.go /first value/,/^}/
+{{code "pipelines/sqleak.go" `/first value/` `/^}/`}}
 
 This is a resource leak: goroutines consume memory and runtime resources, and
 heap references in goroutine stacks keep data from being garbage collected.
@@ -123,21 +128,23 @@
 number of values; send operations complete immediately if there's room in the
 buffer:
 
+{{raw `
 	c := make(chan int, 2) // buffer size 2
 	c <- 1  // succeeds immediately
 	c <- 2  // succeeds immediately
 	c <- 3  // blocks until another goroutine does <-c and receives 1
+`}}
 
 When the number of values to be sent is known at channel creation time, a buffer
 can simplify the code.  For example, we can rewrite `gen` to copy the list of
 integers into a buffered channel and avoid creating a new goroutine:
 
-.code pipelines/sqbuffer.go /func gen/,/^}/
+{{code "pipelines/sqbuffer.go" `/func gen/` `/^}/`}}
 
 Returning to the blocked goroutines in our pipeline, we might consider adding a
 buffer to the outbound channel returned by `merge`:
 
-.code pipelines/sqbuffer.go /func merge/,/unchanged/
+{{code "pipelines/sqbuffer.go" `/func merge/` `/unchanged/`}}
 
 While this fixes the blocked goroutine in this program, this is bad code.  The
 choice of buffer size of 1 here depends on knowing the number of values `merge`
@@ -156,7 +163,7 @@
 channel called `done`.  It sends two values since there are
 potentially two blocked senders:
 
-.code pipelines/sqdone1.go /func main/,/^}/
+{{code "pipelines/sqdone1.go" `/func main/` `/^}/`}}
 
 The sending goroutines replace their send operation with a `select` statement
 that proceeds either when the send on `out` happens or when they receive a value
@@ -166,7 +173,7 @@
 channel, `c`, so the upstream stages are not blocked. (We'll discuss in a moment
 how to allow this loop to return early.)
 
-.code pipelines/sqdone1.go /func merge/,/unchanged/
+{{code "pipelines/sqdone1.go" `/func merge/` `/unchanged/`}}
 
 This approach has a problem: _each_ downstream receiver needs to know the number
 of potentially blocked upstream senders and arrange to signal those senders on
@@ -184,7 +191,7 @@
 `defer` statement, so that all return paths from `main` will signal
 the pipeline stages to exit.
 
-.code pipelines/sqdone3.go /func main/,/^}/
+{{code "pipelines/sqdone3.go" `/func main/` `/^}/`}}
 
 Each of our pipeline stages is now free to return as soon as `done` is closed.
 The `output` routine in `merge` can return without draining its inbound channel,
@@ -192,12 +199,12 @@
 `done` is closed.  `output` ensures `wg.Done` is called on all return paths via
 a `defer` statement:
 
-.code pipelines/sqdone3.go /func merge/,/unchanged/
+{{code "pipelines/sqdone3.go" `/func merge/` `/unchanged/`}}
 
 Similarly, `sq` can return as soon as `done` is closed.  `sq` ensures its `out`
 channel is closed on all return paths via a `defer` statement:
 
-.code pipelines/sqdone3.go /func sq/,/^}/
+{{code "pipelines/sqdone3.go" `/func sq/` `/^}/`}}
 
 Here are the guidelines for pipeline construction:
 
@@ -232,13 +239,13 @@
 The main function of our program invokes a helper function `MD5All`, which
 returns a map from path name to digest value, then sorts and prints the results:
 
-.code pipelines/serial.go /func main/,/^}/
+{{code "pipelines/serial.go" `/func main/` `/^}/`}}
 
 The `MD5All` function is the focus of our discussion.  In
 [serial.go](pipelines/serial.go), the implementation uses no concurrency and
 simply reads and sums each file as it walks the tree.
 
-.code pipelines/serial.go /MD5All/,/^}/
+{{code "pipelines/serial.go" `/MD5All/` `/^}/`}}
 
 ## Parallel digestion
 
@@ -246,19 +253,19 @@
 pipeline.  The first stage, `sumFiles`, walks the tree, digests each file in
 a new goroutine, and sends the results on a channel with value type `result`:
 
-.code pipelines/parallel.go /type result/,/}/  HLresult
+{{code "pipelines/parallel.go" `/type result/` `/}/` "HLresult"}}
 
 `sumFiles` returns two channels: one for the `results` and another for the error
 returned by `filepath.Walk`.  The walk function starts a new goroutine to
 process each regular file, then checks `done`.  If `done` is closed, the walk
 stops immediately:
 
-.code pipelines/parallel.go /func sumFiles/,/^}/
+{{code "pipelines/parallel.go" `/func sumFiles/` `/^}/`}}
 
 `MD5All` receives the digest values from `c`.  `MD5All` returns early on error,
 closing `done` via a `defer`:
 
-.code pipelines/parallel.go /func MD5All/,/^}/  HLdone
+{{code "pipelines/parallel.go" `/func MD5All/` `/^}/` "HLdone"}}
 
 ## Bounded parallelism
 
@@ -274,18 +281,18 @@
 
 The first stage, `walkFiles`, emits the paths of regular files in the tree:
 
-.code pipelines/bounded.go /func walkFiles/,/^}/
+{{code "pipelines/bounded.go" `/func walkFiles/` `/^}/`}}
 
 The middle stage starts a fixed number of `digester` goroutines that receive
 file names from `paths` and send `results` on channel `c`:
 
-.code pipelines/bounded.go /func digester/,/^}/ HLpaths
+{{code "pipelines/bounded.go" `/func digester/` `/^}/` "HLpaths"}}
 
 Unlike our previous examples, `digester` does not close its output channel, as
 multiple goroutines are sending on a shared channel.  Instead, code in `MD5All`
 arranges for the channel to be closed when all the `digesters` are done:
 
-.code pipelines/bounded.go /fixed number/,/End of pipeline/ HLc
+{{code "pipelines/bounded.go" `/fixed number/` `/End of pipeline/` "HLc"}}
 
 We could instead have each digester create and return its own output
 channel, but then we would need additional goroutines to fan-in the
@@ -295,7 +302,7 @@
 error from `errc`.  This check cannot happen any earlier, since before
 this point, `walkFiles` may block sending values downstream:
 
-.code pipelines/bounded.go /m := make/,/^}/ HLerrc
+{{code "pipelines/bounded.go" `/m := make/` `/^}/` "HLerrc"}}
 
 ## Conclusion
 
diff --git a/blog/_content/pipelines/bounded.go b/go.dev/_content/blog/pipelines/bounded.go
similarity index 100%
rename from blog/_content/pipelines/bounded.go
rename to go.dev/_content/blog/pipelines/bounded.go
diff --git a/blog/_content/pipelines/parallel.go b/go.dev/_content/blog/pipelines/parallel.go
similarity index 100%
rename from blog/_content/pipelines/parallel.go
rename to go.dev/_content/blog/pipelines/parallel.go
diff --git a/blog/_content/pipelines/serial.go b/go.dev/_content/blog/pipelines/serial.go
similarity index 100%
rename from blog/_content/pipelines/serial.go
rename to go.dev/_content/blog/pipelines/serial.go
diff --git a/blog/_content/pipelines/sqbuffer.go b/go.dev/_content/blog/pipelines/sqbuffer.go
similarity index 100%
rename from blog/_content/pipelines/sqbuffer.go
rename to go.dev/_content/blog/pipelines/sqbuffer.go
diff --git a/blog/_content/pipelines/sqdone1.go b/go.dev/_content/blog/pipelines/sqdone1.go
similarity index 100%
rename from blog/_content/pipelines/sqdone1.go
rename to go.dev/_content/blog/pipelines/sqdone1.go
diff --git a/blog/_content/pipelines/sqdone2.go b/go.dev/_content/blog/pipelines/sqdone2.go
similarity index 100%
rename from blog/_content/pipelines/sqdone2.go
rename to go.dev/_content/blog/pipelines/sqdone2.go
diff --git a/blog/_content/pipelines/sqdone3.go b/go.dev/_content/blog/pipelines/sqdone3.go
similarity index 100%
rename from blog/_content/pipelines/sqdone3.go
rename to go.dev/_content/blog/pipelines/sqdone3.go
diff --git a/blog/_content/pipelines/sqfan.go b/go.dev/_content/blog/pipelines/sqfan.go
similarity index 100%
rename from blog/_content/pipelines/sqfan.go
rename to go.dev/_content/blog/pipelines/sqfan.go
diff --git a/blog/_content/pipelines/sqleak.go b/go.dev/_content/blog/pipelines/sqleak.go
similarity index 100%
rename from blog/_content/pipelines/sqleak.go
rename to go.dev/_content/blog/pipelines/sqleak.go
diff --git a/blog/_content/pipelines/square.go b/go.dev/_content/blog/pipelines/square.go
similarity index 100%
rename from blog/_content/pipelines/square.go
rename to go.dev/_content/blog/pipelines/square.go
diff --git a/blog/_content/pipelines/square2.go b/go.dev/_content/blog/pipelines/square2.go
similarity index 100%
rename from blog/_content/pipelines/square2.go
rename to go.dev/_content/blog/pipelines/square2.go
diff --git a/blog/_content/pkg.go.dev-2020.article b/go.dev/_content/blog/pkg.go.dev-2020.md
similarity index 96%
rename from blog/_content/pkg.go.dev-2020.article
rename to go.dev/_content/blog/pkg.go.dev-2020.md
index 5255f54..9a84c13 100644
--- a/blog/_content/pkg.go.dev-2020.article
+++ b/go.dev/_content/blog/pkg.go.dev-2020.md
@@ -1,9 +1,10 @@
-# Next steps for pkg.go.dev
-31 Jan 2020
-Summary: What the Go team is planning for pkg.go.dev in 2020.
-
-Julie Qiu
-julie@golang.org
+---
+title: Next steps for pkg.go.dev
+date: 2020-01-31
+by:
+- Julie Qiu
+summary: What the Go team is planning for pkg.go.dev in 2020.
+---
 
 ## Introduction
 
diff --git a/blog/_content/pkgsite-redesign.article b/go.dev/_content/blog/pkgsite-redesign.md
similarity index 93%
rename from blog/_content/pkgsite-redesign.article
rename to go.dev/_content/blog/pkgsite-redesign.md
index db22bff..0a3020b 100644
--- a/blog/_content/pkgsite-redesign.article
+++ b/go.dev/_content/blog/pkgsite-redesign.md
@@ -1,10 +1,11 @@
-# Pkg.go.dev has a new look!
-12:00 10 Nov 2020
-Summary: Announcing a new user experience on pkg.go.dev.
+---
+title: Pkg.go.dev has a new look!
+date: 2020-11-10T12:00:00Z
+by:
+- Julie Qiu
+summary: Announcing a new user experience on pkg.go.dev.
+---
 
-Julie Qiu
-
-##
 
 Since launching [pkg.go.dev](https://pkg.go.dev), we’ve received a lot of great
 feedback on design and usability.
@@ -77,7 +78,7 @@
 we presented a walkthrough of the new site experience in our talk,
 [Level Up: Go Package Discovery and Editor Tooling](https://www.youtube.com/watch?v=n7ayE29b7QA&feature=emb_logo).
 
-.iframe https://www.youtube.com/embed/n7ayE29b7QA 400 650
+{{video "https://www.youtube.com/embed/n7ayE29b7QA" 650 400}}
 
 ## Feedback
 
diff --git a/blog/_content/pkgsite-redesign/meta.png b/go.dev/_content/blog/pkgsite-redesign/meta.png
similarity index 100%
rename from blog/_content/pkgsite-redesign/meta.png
rename to go.dev/_content/blog/pkgsite-redesign/meta.png
Binary files differ
diff --git a/blog/_content/pkgsite-redesign/nav.png b/go.dev/_content/blog/pkgsite-redesign/nav.png
similarity index 100%
rename from blog/_content/pkgsite-redesign/nav.png
rename to go.dev/_content/blog/pkgsite-redesign/nav.png
Binary files differ
diff --git a/blog/_content/pkgsite-redesign/path.png b/go.dev/_content/blog/pkgsite-redesign/path.png
similarity index 100%
rename from blog/_content/pkgsite-redesign/path.png
rename to go.dev/_content/blog/pkgsite-redesign/path.png
Binary files differ
diff --git a/blog/_content/pkgsite.article b/go.dev/_content/blog/pkgsite.md
similarity index 95%
rename from blog/_content/pkgsite.article
rename to go.dev/_content/blog/pkgsite.md
index 15ca815..64a8ec7 100644
--- a/blog/_content/pkgsite.article
+++ b/go.dev/_content/blog/pkgsite.md
@@ -1,10 +1,10 @@
-# Pkg.go.dev is open source!
-15 Jun 2020
+---
+title: Pkg.go.dev is open source!
+date: 2020-06-15
+by:
+- Julie Qiu
+---
 
-Julie Qiu
-julie@golang.org
-
-##
 
 We’re excited to announce that the codebase for
 [pkg.go.dev](https://pkg.go.dev) is now open source.
diff --git a/blog/_content/playground-intro.article b/go.dev/_content/blog/playground-intro.md
similarity index 87%
rename from blog/_content/playground-intro.article
rename to go.dev/_content/blog/playground-intro.md
index 2b3cf1c..db5f498 100644
--- a/blog/_content/playground-intro.article
+++ b/go.dev/_content/blog/playground-intro.md
@@ -1,12 +1,13 @@
-# Introducing the Go Playground
-15 Sep 2010
-Tags: playground
-Summary: Announcing the Go Playground, https://play.golang.org/.
-OldURL: /introducing-go-playground
+---
+title: Introducing the Go Playground
+date: 2010-09-15
+by:
+- Andrew Gerrand
+tags:
+- playground
+summary: "Announcing the Go Playground, https://play.golang.org/."
+---
 
-Andrew Gerrand
-
-##
 
 If you visit [golang.org](https://golang.org/) today you'll see our new look.
 We have given the site a new coat of paint and reorganized its content to
@@ -15,7 +16,7 @@
 the Go documentation tool.
 But the real news is a prominent new feature: the [Go Playground](https://golang.org/).
 
-.image playground-intro/screenshot.png
+{{image "playground-intro/screenshot.png"}}
 
 The Playground allows anyone with a web browser to write Go code that we
 immediately compile,
diff --git a/blog/_content/playground-intro/screenshot.png b/go.dev/_content/blog/playground-intro/screenshot.png
similarity index 100%
rename from blog/_content/playground-intro/screenshot.png
rename to go.dev/_content/blog/playground-intro/screenshot.png
Binary files differ
diff --git a/blog/_content/playground.article b/go.dev/_content/blog/playground.md
similarity index 97%
rename from blog/_content/playground.article
rename to go.dev/_content/blog/playground.md
index e746b99..9045359 100644
--- a/blog/_content/playground.article
+++ b/go.dev/_content/blog/playground.md
@@ -1,9 +1,12 @@
-# Inside the Go Playground
-12 Dec 2013
-Tags: playground
-Summary: How the Go playground works.
-
-Andrew Gerrand
+---
+title: Inside the Go Playground
+date: 2013-12-12
+by:
+- Andrew Gerrand
+tags:
+- playground
+summary: How the Go playground works.
+---
 
 ## Introduction
 
@@ -32,7 +35,7 @@
 
 ## Overview
 
-.image playground/overview.png
+{{image "playground/overview.png"}}
 
 The playground service has three parts:
 
@@ -134,7 +137,7 @@
 The following program prints the current time each second and then exits after
 three seconds. Try running it.
 
-.play -edit playground/time.go /^func main/,$
+{{play "playground/time.go" `/^func main/` `$`}}
 
 How does this work? It is a collaboration between the back end, front end, and client.
 
@@ -149,7 +152,9 @@
 The playback header comprises a magic string, the current time, and the
 length of the write data. A write with a playback header has this structure:
 
+{{raw `
 	0 0 P B <8-byte time> <4-byte data length> <data>
+`}}
 
 The raw output of the program above looks like this:
 
@@ -195,7 +200,7 @@
 The following example program writes data to a file, and then copies
 its contents to standard output. Try running it. (You can edit it, too!)
 
-.play -edit playground/os.go /^func main/,$
+{{play "playground/os.go" `/^func main/` `$`}}
 
 When a process starts, the file system is populated with some devices under
 `/dev` and an empty `/tmp` directory. The program can manipulate the file
@@ -255,7 +260,7 @@
 standard output, and exits. In another goroutine, it makes a connection to the
 listening port, writes a string to the connection, and closes it.
 
-.play -edit playground/net.go /^func main/,$
+{{play "playground/net.go" `/^func main/` `$`}}
 
 The interface to the network is more complex than the one for files, so the
 implementation of the fake network is larger and more complex than the fake
diff --git a/blog/_content/playground/net.go b/go.dev/_content/blog/playground/net.go
similarity index 100%
rename from blog/_content/playground/net.go
rename to go.dev/_content/blog/playground/net.go
diff --git a/blog/_content/playground/os.go b/go.dev/_content/blog/playground/os.go
similarity index 100%
rename from blog/_content/playground/os.go
rename to go.dev/_content/blog/playground/os.go
diff --git a/blog/_content/playground/overview.png b/go.dev/_content/blog/playground/overview.png
similarity index 100%
rename from blog/_content/playground/overview.png
rename to go.dev/_content/blog/playground/overview.png
Binary files differ
diff --git a/blog/_content/playground/time.go b/go.dev/_content/blog/playground/time.go
similarity index 100%
rename from blog/_content/playground/time.go
rename to go.dev/_content/blog/playground/time.go
diff --git a/blog/_content/ports.article b/go.dev/_content/blog/ports.md
similarity index 96%
rename from blog/_content/ports.article
rename to go.dev/_content/blog/ports.md
index b8fb8bf..ec942cd 100644
--- a/blog/_content/ports.article
+++ b/go.dev/_content/blog/ports.md
@@ -1,10 +1,11 @@
-# Go on ARM and Beyond
-17 Dec 2020
-Summary: Go's support for ARM64 and other architectures
+---
+title: Go on ARM and Beyond
+date: 2020-12-17
+by:
+- Russ Cox
+summary: Go's support for ARM64 and other architectures
+---
 
-Russ Cox
-
-##
 
 The industry is abuzz about non-x86 processors recently,
 so we thought it would be worth a brief post about Go’s support for them.
diff --git a/blog/_content/pprof.article b/go.dev/_content/blog/pprof.md
similarity index 97%
rename from blog/_content/pprof.article
rename to go.dev/_content/blog/pprof.md
index ef79de1..3a643f9 100644
--- a/blog/_content/pprof.article
+++ b/go.dev/_content/blog/pprof.md
@@ -1,12 +1,16 @@
-# Profiling Go Programs
-24 Jun 2011
-Tags: benchmark, pprof, profiling, technical
-Summary: How to use Go's built-in profiler to understand and optimize your programs.
-OldURL: /profiling-go-programs
+---
+title: Profiling Go Programs
+date: 2011-06-24
+by:
+- Russ Cox, July 2011; updated by Shenghou Ma, May 2013
+tags:
+- benchmark
+- pprof
+- profiling
+- technical
+summary: How to use Go's built-in profiler to understand and optimize your programs.
+---
 
-Russ Cox, July 2011; updated by Shenghou Ma, May 2013
-
-##
 
 At Scala Days 2011, Robert Hundt presented a paper titled
 [Loop Recognition in C++/Java/Go/Scala.](http://research.google.com/pubs/pub37122.html)
@@ -189,7 +193,7 @@
 A small fragment of
 [the full graph](https://rawgit.com/rsc/benchgraffiti/master/havlak/havlak1.svg) looks like:
 
-.image pprof/havlak1a-75.png
+{{image "pprof/havlak1a-75.png"}}
 
 Each box in the graph corresponds to a single function, and the boxes are sized
 according to the number of samples in which the function was running.
@@ -206,7 +210,7 @@
 
 	(pprof) web mapaccess1
 
-.image pprof/havlak1-hash_lookup-75.png
+{{image "pprof/havlak1-hash_lookup-75.png"}}
 
 If we squint, we can see that the calls to `runtime.mapaccess1_fast64` are being
 made by `main.FindLoops` and `main.DFS`.
@@ -344,6 +348,7 @@
 
 To find the memory allocations, we can list those functions.
 
+{{raw `
 	(pprof) list FindLoops
 	Total: 82.4 MB
 	ROUTINE ====================== main.FindLoops in /home/rsc/g/benchgraffiti/havlak/havlak3.go
@@ -367,6 +372,7 @@
 	  29.5   29.5  288:             nonBackPreds[i] = make(map[int]bool)
 	     .      .  289:     }
 	...
+`}}
 
 It looks like the current bottleneck is the same as the last one: using maps where
 simpler data structures suffice.
@@ -375,6 +381,7 @@
 As an aside, if we run `go tool pprof` with the `--inuse_objects` flag, it will
 report allocation counts instead of sizes:
 
+{{raw `
 	$ go tool pprof --inuse_objects havlak3 havlak3.mprof
 	Adjusting heap profiles for 1-in-524288 sampling rate
 	Welcome to pprof!  For help, type 'help'.
@@ -398,6 +405,7 @@
 	     .      .  289:     }
 	...
 	(pprof)
+`}}
 
 Since the ~200,000 maps account for 29.5 MB, it looks like the initial map allocation
 takes about 150 bytes.
@@ -459,7 +467,7 @@
 
 	(pprof) web mallocgc
 
-.image pprof/havlak4a-mallocgc.png
+{{image "pprof/havlak4a-mallocgc.png"}}
 
 It's hard to tell what's going on in that graph, because there are many nodes with
 small sample numbers obscuring the big ones.
@@ -470,12 +478,13 @@
 	Welcome to pprof!  For help, type 'help'.
 	(pprof) web mallocgc
 
-.image pprof/havlak4a-mallocgc-trim.png
+{{image "pprof/havlak4a-mallocgc-trim.png"}}
 
 We can follow the thick arrows easily now, to see that `FindLoops` is triggering
 most of the garbage collection.
 If we list `FindLoops` we can see that much of it is right at the beginning:
 
+{{raw `
 	(pprof) list FindLoops
 	...
 	     .      .  270: func FindLoops(cfgraph *CFG, lsgraph *LSG) {
@@ -499,6 +508,7 @@
 	     .      .  288:     }
 	...
 	(pprof)
+`}}
 
 Every time `FindLoops` is called, it allocates some sizable bookkeeping structures.
 Since the benchmark calls `FindLoops` 50 times, these add up to a significant amount
@@ -527,6 +537,7 @@
 
 and then have `FindLoops` consult it as a replacement for allocation:
 
+{{raw `
 	if cache.size < size {
 	    cache.size = size
 	    cache.nonBackPreds = make([][]int, size)
@@ -554,6 +565,7 @@
 	types := cache.types[:size]
 	last := cache.last[:size]
 	nodes := cache.nodes[:size]
+`}}
 
 Such a global variable is bad engineering practice, of course: it means that
 concurrent calls to `FindLoops` are now unsafe.
diff --git a/blog/_content/pprof/havlak1-hash_lookup-75.png b/go.dev/_content/blog/pprof/havlak1-hash_lookup-75.png
similarity index 100%
rename from blog/_content/pprof/havlak1-hash_lookup-75.png
rename to go.dev/_content/blog/pprof/havlak1-hash_lookup-75.png
Binary files differ
diff --git a/blog/_content/pprof/havlak1a-75.png b/go.dev/_content/blog/pprof/havlak1a-75.png
similarity index 100%
rename from blog/_content/pprof/havlak1a-75.png
rename to go.dev/_content/blog/pprof/havlak1a-75.png
Binary files differ
diff --git a/blog/_content/pprof/havlak4a-mallocgc-trim.png b/go.dev/_content/blog/pprof/havlak4a-mallocgc-trim.png
similarity index 100%
rename from blog/_content/pprof/havlak4a-mallocgc-trim.png
rename to go.dev/_content/blog/pprof/havlak4a-mallocgc-trim.png
Binary files differ
diff --git a/blog/_content/pprof/havlak4a-mallocgc.png b/go.dev/_content/blog/pprof/havlak4a-mallocgc.png
similarity index 100%
rename from blog/_content/pprof/havlak4a-mallocgc.png
rename to go.dev/_content/blog/pprof/havlak4a-mallocgc.png
Binary files differ
diff --git a/go.dev/_content/blog/preview-of-go-version-1.md b/go.dev/_content/blog/preview-of-go-version-1.md
new file mode 100644
index 0000000..faea4c2
--- /dev/null
+++ b/go.dev/_content/blog/preview-of-go-version-1.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/go1-preview
+---
diff --git a/go.dev/_content/blog/profiling-go-programs.md b/go.dev/_content/blog/profiling-go-programs.md
new file mode 100644
index 0000000..c013819
--- /dev/null
+++ b/go.dev/_content/blog/profiling-go-programs.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/pprof
+---
diff --git a/blog/_content/protobuf-apiv2.article b/go.dev/_content/blog/protobuf-apiv2.md
similarity index 97%
rename from blog/_content/protobuf-apiv2.article
rename to go.dev/_content/blog/protobuf-apiv2.md
index 952d73c..63b61c1 100644
--- a/blog/_content/protobuf-apiv2.article
+++ b/go.dev/_content/blog/protobuf-apiv2.md
@@ -1,14 +1,15 @@
-# A new Go API for Protocol Buffers
-2 Mar 2020
-Tags: protobuf, technical
-Summary: Announcing a major revision of the Go API for protocol buffers.
-OldURL: /a-new-go-api-for-protocol-buffers
-
-Joe Tsai
-
-Damien Neil
-
-Herbie Ong
+---
+title: A new Go API for Protocol Buffers
+date: 2020-03-02
+by:
+- Joe Tsai
+- Damien Neil
+- Herbie Ong
+tags:
+- protobuf
+- technical
+summary: Announcing a major revision of the Go API for protocol buffers.
+---
 
 ## Introduction
 
diff --git a/blog/_content/protobuf.article b/go.dev/_content/blog/protobuf.md
similarity index 89%
rename from blog/_content/protobuf.article
rename to go.dev/_content/blog/protobuf.md
index c1726ea..3c8ca48 100644
--- a/blog/_content/protobuf.article
+++ b/go.dev/_content/blog/protobuf.md
@@ -1,12 +1,14 @@
-# Third-party libraries: goprotobuf and beyond
-20 Apr 2010
-Tags: protobuf, community
-Summary: Announcing Go support for Protocol Buffers, Google's data interchange format.
-OldURL: /third-party-libraries-goprotobuf-and
+---
+title: "Third-party libraries: goprotobuf and beyond"
+date: 2010-04-20
+by:
+- Andrew Gerrand
+tags:
+- protobuf
+- community
+summary: Announcing Go support for Protocol Buffers, Google's data interchange format.
+---
 
-Andrew Gerrand
-
-##
 
 On March 24, Rob Pike announced [goprotobuf](http://code.google.com/p/goprotobuf/),
 the Go bindings of Google's data interchange format [Protocol Buffers](http://code.google.com/apis/protocolbuffers/docs/overview.html),
diff --git a/blog/_content/publishing-go-modules.article b/go.dev/_content/blog/publishing-go-modules.md
similarity index 97%
rename from blog/_content/publishing-go-modules.article
rename to go.dev/_content/blog/publishing-go-modules.md
index fc7134b..7b95a8d 100644
--- a/blog/_content/publishing-go-modules.article
+++ b/go.dev/_content/blog/publishing-go-modules.md
@@ -1,9 +1,13 @@
-# Publishing Go Modules
-26 Sep 2019
-Tags: tools, versioning
-Summary: How to write and publish modules for use as dependencies.
-
-Tyler Bui-Palsulich
+---
+title: Publishing Go Modules
+date: 2019-09-26
+by:
+- Tyler Bui-Palsulich
+tags:
+- tools
+- versioning
+summary: How to write and publish modules for use as dependencies.
+---
 
 ## Introduction
 
diff --git a/blog/_content/qihoo.article b/go.dev/_content/blog/qihoo.md
similarity index 94%
rename from blog/_content/qihoo.article
rename to go.dev/_content/blog/qihoo.md
index d34dd6d..9d04b3c 100644
--- a/blog/_content/qihoo.article
+++ b/go.dev/_content/blog/qihoo.md
@@ -1,10 +1,11 @@
-# Qihoo 360 and Go
-6 Jul 2015
-Summary: How Qihoo 360 uses Go.
+---
+title: Qihoo 360 and Go
+date: 2015-07-06
+by:
+- Yang Zhou
+summary: How Qihoo 360 uses Go.
+---
 
-Yang Zhou
-
-##
 
 _This guest blog post was written by Yang Zhou, Software Engineer at Qihoo 360._
 
@@ -51,7 +52,7 @@
     to reduce creation of buffers and objects during communication.
   - Use Objects and Memory pools appropriately, to reduce the load on the GC.
 
-.image qihoo/image00.png
+{{image "qihoo/image00.png"}}
 
   - Use a Task Pool, a mechanism with a group of long-lived goroutines consuming
     global task or message queues sent by connection goroutines,
@@ -75,11 +76,11 @@
 This can all attributed to the development convenience of Go.
 Below you can find the up-to-date system architecture:
 
-.image qihoo/image01.png
+{{image "qihoo/image01.png"}}
 
 The continuous improvement journey can be illustrated by a table:
 
-.image qihoo/table.png
+{{image "qihoo/table.png"}}
 
 Also, no temporary release of memory or system reboot is required after these
 optimizations.
@@ -89,8 +90,8 @@
 status, pinning down any potential risks. Here is a screen shot of the system
 in action:
 
-.image qihoo/image02.png
-.image qihoo/image03.png
+{{image "qihoo/image02.png"}}
+{{image "qihoo/image03.png"}}
 
 The great thing about this platform is that we can actually simulate the
 connection and behavior of millions of online users, by applying the
diff --git a/blog/_content/qihoo/image00.png b/go.dev/_content/blog/qihoo/image00.png
similarity index 100%
rename from blog/_content/qihoo/image00.png
rename to go.dev/_content/blog/qihoo/image00.png
Binary files differ
diff --git a/blog/_content/qihoo/image01.png b/go.dev/_content/blog/qihoo/image01.png
similarity index 100%
rename from blog/_content/qihoo/image01.png
rename to go.dev/_content/blog/qihoo/image01.png
Binary files differ
diff --git a/blog/_content/qihoo/image02.png b/go.dev/_content/blog/qihoo/image02.png
similarity index 100%
rename from blog/_content/qihoo/image02.png
rename to go.dev/_content/blog/qihoo/image02.png
Binary files differ
diff --git a/blog/_content/qihoo/image03.png b/go.dev/_content/blog/qihoo/image03.png
similarity index 100%
rename from blog/_content/qihoo/image03.png
rename to go.dev/_content/blog/qihoo/image03.png
Binary files differ
diff --git a/blog/_content/qihoo/table.png b/go.dev/_content/blog/qihoo/table.png
similarity index 100%
rename from blog/_content/qihoo/table.png
rename to go.dev/_content/blog/qihoo/table.png
Binary files differ
diff --git a/blog/_content/race-detector.article b/go.dev/_content/blog/race-detector.md
similarity index 95%
rename from blog/_content/race-detector.article
rename to go.dev/_content/blog/race-detector.md
index 657bec4..46c86eb 100644
--- a/blog/_content/race-detector.article
+++ b/go.dev/_content/blog/race-detector.md
@@ -1,11 +1,14 @@
-# Introducing the Go Race Detector
-26 Jun 2013
-Tags: concurrency, technical
-Summary: How and why to use the Go race detector to improve your programs.
-
-Dmitry Vyukov
-
-Andrew Gerrand
+---
+title: Introducing the Go Race Detector
+date: 2013-06-26
+by:
+- Dmitry Vyukov
+- Andrew Gerrand
+tags:
+- concurrency
+- technical
+summary: How and why to use the Go race detector to improve your programs.
+---
 
 ## Introduction
 
@@ -65,6 +68,7 @@
 
 To try out the race detector for yourself, copy this example program into `racy.go`:
 
+{{raw `
 	package main
 
 	import "fmt"
@@ -80,6 +84,7 @@
 		fmt.Println("Hello,", m["name"])
 		<-done
 	}
+`}}
 
 Then run it with the race detector enabled:
 
@@ -99,7 +104,7 @@
 uses the [`Reset`](https://golang.org/pkg/time/#Timer.Reset) method to
 schedule the next message, re-using the `Timer` each time.
 
-.play -numbers race-detector/timer.go /func main/,$
+{{play "race-detector/timer.go" `/func main/` `$` 0}}
 
 This looks like reasonable code, but under certain circumstances it fails in a surprising way:
 
@@ -143,7 +148,7 @@
 To fix the race condition we change the code to read and write the variable
 `t` only from the main goroutine:
 
-.play -numbers race-detector/timer-fixed.go /func main/,/^}/
+{{play "race-detector/timer-fixed.go" `/func main/` `/^}/` 0}}
 
 Here the main goroutine is wholly responsible for setting and resetting the
 `Timer` `t` and a new reset channel communicates the need to reset the timer in
@@ -205,7 +210,7 @@
 Here is the known-racy code in `io/ioutil`, where `Discard` is a
 `devNull` that shares a single buffer between all of its users.
 
-.code race-detector/blackhole.go /var blackHole/,/^}/
+{{code "race-detector/blackhole.go" `/var blackHole/` `/^}/`}}
 
 Brad's program includes a `trackDigestReader` type, which wraps an `io.Reader`
 and records the hash digest of what it reads.
diff --git a/blog/_content/race-detector/blackhole.go b/go.dev/_content/blog/race-detector/blackhole.go
similarity index 100%
rename from blog/_content/race-detector/blackhole.go
rename to go.dev/_content/blog/race-detector/blackhole.go
diff --git a/blog/_content/race-detector/timer-fixed.go b/go.dev/_content/blog/race-detector/timer-fixed.go
similarity index 100%
rename from blog/_content/race-detector/timer-fixed.go
rename to go.dev/_content/blog/race-detector/timer-fixed.go
diff --git a/blog/_content/race-detector/timer.go b/go.dev/_content/blog/race-detector/timer.go
similarity index 100%
rename from blog/_content/race-detector/timer.go
rename to go.dev/_content/blog/race-detector/timer.go
diff --git a/go.dev/_content/blog/real-go-projects-smarttwitter-and-webgo.md b/go.dev/_content/blog/real-go-projects-smarttwitter-and-webgo.md
new file mode 100644
index 0000000..56a0199
--- /dev/null
+++ b/go.dev/_content/blog/real-go-projects-smarttwitter-and-webgo.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/smarttwitter
+---
diff --git a/go.dev/_content/blog/share-memory-by-communicating.md b/go.dev/_content/blog/share-memory-by-communicating.md
new file mode 100644
index 0000000..ca6d686
--- /dev/null
+++ b/go.dev/_content/blog/share-memory-by-communicating.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/codelab-share
+---
diff --git a/blog/_content/slices-intro.article b/go.dev/_content/blog/slices-intro.md
similarity index 95%
rename from blog/_content/slices-intro.article
rename to go.dev/_content/blog/slices-intro.md
index 7567c43..271ebfa 100644
--- a/blog/_content/slices-intro.article
+++ b/go.dev/_content/blog/slices-intro.md
@@ -1,10 +1,13 @@
-# Go Slices: usage and internals
-5 Jan 2011
-Tags: slice, technical
-Summary: How to use Go slices, and how they work.
-OldURL: /go-slices-usage-and-internals
-
-Andrew Gerrand
+---
+title: "Go Slices: usage and internals"
+date: 2011-01-05
+by:
+- Andrew Gerrand
+tags:
+- slice
+- technical
+summary: How to use Go slices, and how they work.
+---
 
 ## Introduction
 
@@ -38,7 +41,7 @@
 
 The in-memory representation of `[4]int` is just four integer values laid out sequentially:
 
-.image slices-intro/slice-array.png
+{{image "slices-intro/slice-array.png"}}
 
 Go's arrays are values. An array variable denotes the entire array;
 it is not a pointer to the first array element (as would be the case in C).
@@ -125,11 +128,11 @@
 It consists of a pointer to the array, the length of the segment,
 and its capacity (the maximum length of the segment).
 
-.image slices-intro/slice-struct.png
+{{image "slices-intro/slice-struct.png"}}
 
 Our variable `s`, created earlier by `make([]byte, 5)`, is structured like this:
 
-.image slices-intro/slice-1.png
+{{image "slices-intro/slice-1.png"}}
 
 The length is the number of elements referred to by the slice.
 The capacity is the number of elements in the underlying array (beginning
@@ -141,7 +144,7 @@
 
 	s = s[2:4]
 
-.image slices-intro/slice-2.png
+{{image "slices-intro/slice-2.png"}}
 
 Slicing does not copy the slice's data. It creates a new slice value that
 points to the original array.
@@ -160,7 +163,7 @@
 
 	s = s[:cap(s)]
 
-.image slices-intro/slice-3.png
+{{image "slices-intro/slice-3.png"}}
 
 A slice cannot be grown beyond its capacity.
 Attempting to do so will cause a runtime panic,
diff --git a/blog/_content/slices-intro/slice-1.png b/go.dev/_content/blog/slices-intro/slice-1.png
similarity index 100%
rename from blog/_content/slices-intro/slice-1.png
rename to go.dev/_content/blog/slices-intro/slice-1.png
Binary files differ
diff --git a/blog/_content/slices-intro/slice-2.png b/go.dev/_content/blog/slices-intro/slice-2.png
similarity index 100%
rename from blog/_content/slices-intro/slice-2.png
rename to go.dev/_content/blog/slices-intro/slice-2.png
Binary files differ
diff --git a/blog/_content/slices-intro/slice-3.png b/go.dev/_content/blog/slices-intro/slice-3.png
similarity index 100%
rename from blog/_content/slices-intro/slice-3.png
rename to go.dev/_content/blog/slices-intro/slice-3.png
Binary files differ
diff --git a/blog/_content/slices-intro/slice-array.png b/go.dev/_content/blog/slices-intro/slice-array.png
similarity index 100%
rename from blog/_content/slices-intro/slice-array.png
rename to go.dev/_content/blog/slices-intro/slice-array.png
Binary files differ
diff --git a/blog/_content/slices-intro/slice-struct.png b/go.dev/_content/blog/slices-intro/slice-struct.png
similarity index 100%
rename from blog/_content/slices-intro/slice-struct.png
rename to go.dev/_content/blog/slices-intro/slice-struct.png
Binary files differ
diff --git a/blog/_content/slices.article b/go.dev/_content/blog/slices.md
similarity index 92%
rename from blog/_content/slices.article
rename to go.dev/_content/blog/slices.md
index 58f10e1..0da12d3 100644
--- a/blog/_content/slices.article
+++ b/go.dev/_content/blog/slices.md
@@ -1,9 +1,16 @@
-# Arrays, slices (and strings): The mechanics of 'append'
-26 Sep 2013
-Tags: array, slice, string, copy, append
-Summary: How Go arrays and slices work, and how to use copy and append.
-
-Rob Pike
+---
+title: "Arrays, slices (and strings): The mechanics of 'append'"
+date: 2013-09-26
+by:
+- Rob Pike
+tags:
+- array
+- slice
+- string
+- copy
+- append
+summary: How Go arrays and slices work, and how to use copy and append.
+---
 
 ## Introduction
 
@@ -43,7 +50,7 @@
 
 The declaration
 
-.code slices/prog010.go /var buffer/
+{{code "slices/prog010.go" `/var buffer/`}}
 
 declares the variable `buffer`, which holds 256 bytes.
 The type of `buffer` includes its size, `[256]byte`.
@@ -83,7 +90,7 @@
 a slice that describes elements 100 through 150 (to be precise, 100 through 149,
 inclusive) by _slicing_ the array:
 
-.code slices/prog010.go /var slice/
+{{code "slices/prog010.go" `/var slice/`}}
 
 In that snippet we used the full variable declaration to be explicit.
 The variable `slice` has type `[]byte`, pronounced "slice of bytes",
@@ -182,14 +189,14 @@
 
 Consider this simple function:
 
-.code slices/prog010.go /^func/,/^}/
+{{code "slices/prog010.go" `/^func/` `/^}/`}}
 
 It does just what its name implies, iterating over the indices of a slice
 (using a `for` `range` loop), incrementing its elements.
 
 Try it:
 
-.play -edit slices/prog010.go /^func main/,/^}/
+{{play "slices/prog010.go" `/^func main/` `/^}/`}}
 
 (You can edit and re-execute these runnable snippets if you want to explore.)
 
@@ -202,7 +209,7 @@
 
 The argument to the function really is a copy, as this example shows:
 
-.play -edit slices/prog020.go /^func/,$
+{{play "slices/prog020.go" `/^func/` `$`}}
 
 Here we see that the _contents_ of a slice argument can be modified by a function,
 but its _header_ cannot.
@@ -218,7 +225,7 @@
 Another way to have a function modify the slice header is to pass a pointer to it.
 Here's a variant of our previous example that does this:
 
-.play -edit slices/prog030.go /^func/,$
+{{play "slices/prog030.go" `/^func/` `$`}}
 
 It seems clumsy in that example, especially dealing with the extra level of indirection
 (a temporary variable helps),
@@ -228,7 +235,7 @@
 Let's say we wanted to have a method on a slice that truncates it at the final slash.
 We could write it like this:
 
-.play -edit slices/prog040.go /^type/,$
+{{play "slices/prog040.go" `/^type/` `$`}}
 
 If you run this example you'll see that it works properly, updating the slice in the caller.
 
@@ -239,7 +246,7 @@
 the ASCII letters in the path (parochially ignoring non-English names), the method could
 be a value because the value receiver will still point to the same underlying array.
 
-.play -edit slices/prog050.go /^type/,$
+{{play "slices/prog050.go" `/^type/` `$`}}
 
 Here the `ToUpper` method uses two variables in the `for` `range` construct
 to capture the index and slice element.
@@ -253,11 +260,11 @@
 
 Look at the following function that extends its argument slice of `ints` by one element:
 
-.code slices/prog060.go /^func Extend/,/^}/
+{{code "slices/prog060.go" `/^func Extend/` `/^}/`}}
 
 (Why does it need to return the modified slice?) Now run it:
 
-.play -edit slices/prog060.go /^func main/,/^}/
+{{play "slices/prog060.go" `/^func main/` `/^}/`}}
 
 See how the slice grows until... it doesn't.
 
@@ -312,11 +319,11 @@
 length of the array that `make` allocates to hold the slice data.
 This call creates a slice of length 10 with room for 5 more (15-10), as you can see by running it:
 
-.play -edit slices/prog070.go /slice/,/fmt/
+{{play "slices/prog070.go" `/slice/` `/fmt/`}}
 
 This snippet doubles the capacity of our `int` slice but keeps its length the same:
 
-.play -edit slices/prog080.go /slice/,/OMIT/
+{{play "slices/prog080.go" `/slice/` `/OMIT/`}}
 
 After running this code the slice has much more room to grow before needing another reallocation.
 
@@ -338,7 +345,7 @@
 Its arguments are two slices, and it copies the data from the right-hand argument to the left-hand argument.
 Here's our example rewritten to use `copy`:
 
-.play -edit slices/prog090.go /newSlice/,/newSlice/
+{{play "slices/prog090.go" `/newSlice/` `/newSlice/`}}
 
 The `copy` function is smart.
 It only copies what it can, paying attention to the lengths of both arguments.
@@ -350,7 +357,7 @@
 items around in a single slice.
 Here's how to use `copy` to insert a value into the middle of a slice.
 
-.code slices/prog100.go /Insert/,/^}/
+{{code "slices/prog100.go" `/Insert/` `/^}/`}}
 
 There are a couple of things to notice in this function.
 First, of course, it must return the updated slice because its length has changed.
@@ -375,7 +382,7 @@
 
 Now that's out of the way, let's run our `Insert` function.
 
-.play -edit slices/prog100.go /make/,/OMIT/
+{{play "slices/prog100.go" `/make/` `/OMIT/`}}
 
 ## Append: An example
 
@@ -386,13 +393,13 @@
 Now we have the pieces in place to fix that, so let's write a robust implementation of
 `Extend` for integer slices.
 
-.code slices/prog110.go /func Extend/,/^}/
+{{code "slices/prog110.go" `/func Extend/` `/^}/`}}
 
 In this case it's especially important to return the slice, since when it reallocates
 the resulting slice describes a completely different array.
 Here's a little snippet to demonstrate what happens as the slice fills up:
 
-.play -edit slices/prog110.go /START/,/END/
+{{play "slices/prog110.go" `/START/` `/END/`}}
 
 Notice the reallocation when the initial array of size 5 is filled up.
 Both the capacity and the address of the zeroth element change when the new array is allocated.
@@ -414,37 +421,37 @@
 Those arguments are exactly a slice of `int` as far as the implementation
 of `Append` is concerned, as you can see:
 
-.code slices/prog120.go /Append/,/^}/
+{{code "slices/prog120.go" `/Append/` `/^}/`}}
 
 Notice the `for` `range` loop iterating over the elements of the `items` argument, which has implied type `[]int`.
 Also notice the use of the blank identifier `_` to discard the index in the loop, which we don't need in this case.
 
 Try it:
 
-.play -edit slices/prog120.go /START/,/END/
+{{play "slices/prog120.go" `/START/` `/END/`}}
 
 Another new technique in this example is that we initialize the slice by writing a composite literal,
 which consists of the type of the slice followed by its elements in braces:
 
-.code slices/prog120.go /slice := /
+{{code "slices/prog120.go" `/slice := /`}}
 
 The `Append` function is interesting for another reason.
 Not only can we append elements, we can append a whole second slice
 by "exploding" the slice into arguments using the `...` notation at the call site:
 
-.play -edit slices/prog130.go /START/,/END/
+{{play "slices/prog130.go" `/START/` `/END/`}}
 
 Of course, we can make `Append` more efficient by allocating no more than once,
 building on the innards of `Extend`:
 
-.code slices/prog140.go /Append/,/^}/
+{{code "slices/prog140.go" `/Append/` `/^}/`}}
 
 Here, notice how we use `copy` twice, once to move the slice data to the newly
 allocated memory, and then to copy the appending items to the end of the old data.
 
 Try it; the behavior is the same as before:
 
-.play -edit slices/prog140.go /START/,/END/
+{{play "slices/prog140.go" `/START/` `/END/`}}
 
 ## Append: The built-in function
 
@@ -463,7 +470,7 @@
 
 Here are some one-liners intermingled with print statements. Try them, edit them and explore:
 
-.play -edit slices/prog150.go /START/,/END/
+{{play "slices/prog150.go" `/START/` `/END/`}}
 
 It's worth taking a moment to think about the final one-liner of that example in detail to understand
 how the design of slices makes it possible for this simple call to work correctly.
diff --git a/blog/_content/slices/prog010.go b/go.dev/_content/blog/slices/prog010.go
similarity index 100%
rename from blog/_content/slices/prog010.go
rename to go.dev/_content/blog/slices/prog010.go
diff --git a/blog/_content/slices/prog020.go b/go.dev/_content/blog/slices/prog020.go
similarity index 100%
rename from blog/_content/slices/prog020.go
rename to go.dev/_content/blog/slices/prog020.go
diff --git a/blog/_content/slices/prog030.go b/go.dev/_content/blog/slices/prog030.go
similarity index 100%
rename from blog/_content/slices/prog030.go
rename to go.dev/_content/blog/slices/prog030.go
diff --git a/blog/_content/slices/prog040.go b/go.dev/_content/blog/slices/prog040.go
similarity index 100%
rename from blog/_content/slices/prog040.go
rename to go.dev/_content/blog/slices/prog040.go
diff --git a/blog/_content/slices/prog050.go b/go.dev/_content/blog/slices/prog050.go
similarity index 100%
rename from blog/_content/slices/prog050.go
rename to go.dev/_content/blog/slices/prog050.go
diff --git a/blog/_content/slices/prog060.go b/go.dev/_content/blog/slices/prog060.go
similarity index 100%
rename from blog/_content/slices/prog060.go
rename to go.dev/_content/blog/slices/prog060.go
diff --git a/blog/_content/slices/prog070.go b/go.dev/_content/blog/slices/prog070.go
similarity index 100%
rename from blog/_content/slices/prog070.go
rename to go.dev/_content/blog/slices/prog070.go
diff --git a/blog/_content/slices/prog080.go b/go.dev/_content/blog/slices/prog080.go
similarity index 100%
rename from blog/_content/slices/prog080.go
rename to go.dev/_content/blog/slices/prog080.go
diff --git a/blog/_content/slices/prog090.go b/go.dev/_content/blog/slices/prog090.go
similarity index 100%
rename from blog/_content/slices/prog090.go
rename to go.dev/_content/blog/slices/prog090.go
diff --git a/blog/_content/slices/prog100.go b/go.dev/_content/blog/slices/prog100.go
similarity index 100%
rename from blog/_content/slices/prog100.go
rename to go.dev/_content/blog/slices/prog100.go
diff --git a/blog/_content/slices/prog110.go b/go.dev/_content/blog/slices/prog110.go
similarity index 100%
rename from blog/_content/slices/prog110.go
rename to go.dev/_content/blog/slices/prog110.go
diff --git a/blog/_content/slices/prog120.go b/go.dev/_content/blog/slices/prog120.go
similarity index 100%
rename from blog/_content/slices/prog120.go
rename to go.dev/_content/blog/slices/prog120.go
diff --git a/blog/_content/slices/prog130.go b/go.dev/_content/blog/slices/prog130.go
similarity index 100%
rename from blog/_content/slices/prog130.go
rename to go.dev/_content/blog/slices/prog130.go
diff --git a/blog/_content/slices/prog140.go b/go.dev/_content/blog/slices/prog140.go
similarity index 100%
rename from blog/_content/slices/prog140.go
rename to go.dev/_content/blog/slices/prog140.go
diff --git a/blog/_content/slices/prog150.go b/go.dev/_content/blog/slices/prog150.go
similarity index 100%
rename from blog/_content/slices/prog150.go
rename to go.dev/_content/blog/slices/prog150.go
diff --git a/blog/_content/smarttwitter.article b/go.dev/_content/blog/smarttwitter.md
similarity index 93%
rename from blog/_content/smarttwitter.article
rename to go.dev/_content/blog/smarttwitter.md
index 9bff1c9..fe34596 100644
--- a/blog/_content/smarttwitter.article
+++ b/go.dev/_content/blog/smarttwitter.md
@@ -1,12 +1,13 @@
-# Real Go Projects: SmartTwitter and web.go
-19 Oct 2010
-Tags: guest
-Summary: How Michael Hoisie used Go to build SmartTwitter and web.go.
-OldURL: /real-go-projects-smarttwitter-and-webgo
+---
+title: "Real Go Projects: SmartTwitter and web.go"
+date: 2010-10-19
+by:
+- Michael Hoisie
+tags:
+- guest
+summary: How Michael Hoisie used Go to build SmartTwitter and web.go.
+---
 
-Michael Hoisie
-
-##
 
 _This week's article is written by_ [_Michael Hoisie_](http://www.hoisie.com/).
 _A programmer based in San Francisco, he is one of Go's early adopters and the author of several popular Go libraries. He describes his experiences using Go:_
diff --git a/go.dev/_content/blog/spotlight-on-external-go-libraries.md b/go.dev/_content/blog/spotlight-on-external-go-libraries.md
new file mode 100644
index 0000000..d70aeb5
--- /dev/null
+++ b/go.dev/_content/blog/spotlight-on-external-go-libraries.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/external-libraries
+---
diff --git a/blog/_content/stable-releases.article b/go.dev/_content/blog/stable-releases.md
similarity index 92%
rename from blog/_content/stable-releases.article
rename to go.dev/_content/blog/stable-releases.md
index a7a568c..6107295 100644
--- a/blog/_content/stable-releases.article
+++ b/go.dev/_content/blog/stable-releases.md
@@ -1,12 +1,13 @@
-# Go becomes more stable
-16 Mar 2011
-Tags: release
-Summary: Moving from weekly unstable Go releases toward less frequent, more stable ones.
-OldURL: /go-becomes-more-stable
+---
+title: Go becomes more stable
+date: 2011-03-16
+by:
+- Andrew Gerrand
+tags:
+- release
+summary: Moving from weekly unstable Go releases toward less frequent, more stable ones.
+---
 
-Andrew Gerrand
-
-##
 
 The Go project is moving fast. As we learn more about Go we are compelled
 to change our tools,
diff --git a/blog/_content/stackoverflow.article b/go.dev/_content/blog/stackoverflow.md
similarity index 94%
rename from blog/_content/stackoverflow.article
rename to go.dev/_content/blog/stackoverflow.md
index 02fac3f..7fefacb 100644
--- a/blog/_content/stackoverflow.article
+++ b/go.dev/_content/blog/stackoverflow.md
@@ -1,11 +1,13 @@
-# The Go Collective on Stack Overflow
-23 Jun 2021
-Tags: community
-Summary: Announcing the Go Collective, a new experience for Go on Stack Overflow.
+---
+title: The Go Collective on Stack Overflow
+date: 2021-06-23
+by:
+- Steve Francia
+tags:
+- community
+summary: Announcing the Go Collective, a new experience for Go on Stack Overflow.
+---
 
-Steve Francia
-
-##
 
 Since the earliest days of Go,
 Stack Overflow has been a significant part of the Go user experience.
diff --git a/blog/_content/stackoverflow/stackoverflow.png b/go.dev/_content/blog/stackoverflow/stackoverflow.png
similarity index 100%
rename from blog/_content/stackoverflow/stackoverflow.png
rename to go.dev/_content/blog/stackoverflow/stackoverflow.png
Binary files differ
diff --git a/blog/_content/stathat.article b/go.dev/_content/blog/stathat.md
similarity index 96%
rename from blog/_content/stathat.article
rename to go.dev/_content/blog/stathat.md
index 6d82328..67d44b1 100644
--- a/blog/_content/stathat.article
+++ b/go.dev/_content/blog/stathat.md
@@ -1,10 +1,12 @@
-# Building StatHat with Go
-19 Dec 2011
-Tags: guest
-Summary: How StatHat uses Go, and why they chose it.
-OldURL: /building-stathat-with-go
-
-Patrick Crosby
+---
+title: Building StatHat with Go
+date: 2011-12-19
+by:
+- Patrick Crosby
+tags:
+- guest
+summary: How StatHat uses Go, and why they chose it.
+---
 
 ## Introduction
 
@@ -29,7 +31,7 @@
 
 Here's an example of a StatHat graph of the temperature in NYC, Chicago, and San Francisco:
 
-.image stathat/weather.png
+{{image "stathat/weather.png"}}
 
 ## Architecture Overview
 
@@ -42,7 +44,7 @@
 different optimization strategies for the API service than a web application
 interacting with humans.
 
-.image stathat/architecture.png
+{{image "stathat/architecture.png"}}
 
 The web application service is multi-tiered.
 The web server processes all requests and sends them to an interactor layer.
diff --git a/blog/_content/stathat/architecture.png b/go.dev/_content/blog/stathat/architecture.png
similarity index 100%
rename from blog/_content/stathat/architecture.png
rename to go.dev/_content/blog/stathat/architecture.png
Binary files differ
diff --git a/blog/_content/stathat/weather.png b/go.dev/_content/blog/stathat/weather.png
similarity index 100%
rename from blog/_content/stathat/weather.png
rename to go.dev/_content/blog/stathat/weather.png
Binary files differ
diff --git a/blog/_content/store.article b/go.dev/_content/blog/store.md
similarity index 86%
rename from blog/_content/store.article
rename to go.dev/_content/blog/store.md
index 6340446..2e60adf 100644
--- a/blog/_content/store.article
+++ b/go.dev/_content/blog/store.md
@@ -1,10 +1,11 @@
-# Announcing The New Go Store
-18 Jul 2019
-Summary: Unfortunately, the Go store is offline.
+---
+title: Announcing The New Go Store
+date: 2019-07-18
+by:
+- Cassandra Salisbury
+summary: Unfortunately, the Go store is offline.
+---
 
-Cassandra Salisbury
-
-##
 
 **October 1, 2019, Update:** _The Go Store is currently offline._
 _We are sorry for any inconvenience._
@@ -14,7 +15,7 @@
 We are even more excited to announce that **100% of the proceeds** from the Go store go directly to GoBridge.
 [GoBridge](https://github.com/gobridge/about-us) is a non-profit organization focused on building bridges to educate underrepresented groups by teaching technical skills and fostering diversity in the Go community.
 
-.image store/gophers.jpg
+{{image "store/gophers.jpg"}}
 
 At the **Go store** you’ll find our beloved gopher plushies and vinyls as well as new merchandise.
 Visit the store for 20% off with code **Gopher20** through Sunday, July 21st at 11:59 PM PST.
diff --git a/blog/_content/store/gophers.jpg b/go.dev/_content/blog/store/gophers.jpg
similarity index 100%
rename from blog/_content/store/gophers.jpg
rename to go.dev/_content/blog/store/gophers.jpg
Binary files differ
diff --git a/blog/_content/strings.article b/go.dev/_content/blog/strings.md
similarity index 93%
rename from blog/_content/strings.article
rename to go.dev/_content/blog/strings.md
index 4fb6f20..f79cd5a 100644
--- a/blog/_content/strings.article
+++ b/go.dev/_content/blog/strings.md
@@ -1,9 +1,15 @@
-# Strings, bytes, runes and characters in Go
-23 Oct 2013
-Tags: strings, bytes, runes, characters
-Summary: How strings work in Go, and how to use them.
-
-Rob Pike
+---
+title: Strings, bytes, runes and characters in Go
+date: 2013-10-23
+by:
+- Rob Pike
+tags:
+- strings
+- bytes
+- runes
+- characters
+summary: How strings work in Go, and how to use them.
+---
 
 ## Introduction
 
@@ -47,7 +53,7 @@
 `\xNN` notation to define a string constant holding some peculiar byte values.
 (Of course, bytes range from hexadecimal values 00 through FF, inclusive.)
 
-.code strings/basic.go /const sample/
+{{code "strings/basic.go" `/const sample/`}}
 
 ## Printing strings
 
@@ -55,7 +61,7 @@
 valid UTF-8, printing the string directly will produce ugly output.
 The simple print statement
 
-.code strings/basic.go /println/,/println/
+{{code "strings/basic.go" `/println/` `/println/`}}
 
 produces this mess (whose exact appearance varies with the environment):
 
@@ -66,7 +72,7 @@
 The most obvious is to loop over its contents and pull out the bytes
 individually, as in this `for` loop:
 
-.code strings/basic.go /byte loop/,/byte loop/
+{{code "strings/basic.go" `/byte loop/` `/byte loop/`}}
 
 As implied up front, indexing a string accesses individual bytes, not
 characters. We'll return to that topic in detail below. For now, let's
@@ -83,7 +89,7 @@
 It just dumps out the sequential bytes of the string as hexadecimal
 digits, two per byte.
 
-.code strings/basic.go /percent x/,/percent x/
+{{code "strings/basic.go" `/percent x/` `/percent x/`}}
 
 Compare its output to that above:
 
@@ -93,7 +99,7 @@
 space between the `%` and the `x`. Compare the format string
 used here to the one above,
 
-.code strings/basic.go /percent space x/,/percent space x/
+{{code "strings/basic.go" `/percent space x/` `/percent space x/`}}
 
 and notice how the bytes come
 out with spaces between, making the result a little less imposing:
@@ -103,7 +109,7 @@
 There's more. The `%q` (quoted) verb will escape any non-printable
 byte sequences in a string so the output is unambiguous.
 
-.code strings/basic.go /percent q/,/percent q/
+{{code "strings/basic.go" `/percent q/` `/percent q/`}}
 
 This technique is handy when much of the string is
 intelligible as text but there are peculiarities to root out; it produces:
@@ -123,7 +129,7 @@
 The result is that it exposes the Unicode values of properly formatted UTF-8
 that represents non-ASCII data in the string:
 
-.code strings/basic.go /percent plus q/,/percent plus q/
+{{code "strings/basic.go" `/percent plus q/` `/percent plus q/`}}
 
 With that format, the Unicode value of the Swedish symbol shows up as a
 `\u` escape:
@@ -138,7 +144,7 @@
 Here's the full set of printing options we've listed, presented as
 a complete program you can run (and edit) right in the browser:
 
-.play -edit strings/basic.go /package/,/^}/
+{{play "strings/basic.go" `/package/` `/^}/`}}
 
 [Exercise: Modify the examples above to use a slice of bytes
 instead of a string. Hint: Use a conversion to create the slice.]
@@ -161,7 +167,7 @@
 so it can contain only literal text. (Regular strings, enclosed by double
 quotes, can contain escape sequences as we showed above.)
 
-.play -edit strings/utf8.go /^func/,/^}/
+{{play "strings/utf8.go" `/^func/` `/^}/`}}
 
 The output is:
 
@@ -277,7 +283,7 @@
 Here's an example using yet another handy `Printf` format, `%#U`, which shows
 the code point's Unicode value and its printed representation:
 
-.play -edit strings/range.go /const/,/}/
+{{play "strings/range.go" `/const/` `/}/`}}
 
 The output shows how each code point occupies multiple bytes:
 
@@ -304,7 +310,7 @@
 The return values from the function are the rune and its width in
 UTF-8-encoded bytes.
 
-.play -edit strings/encoding.go /const/,/}/
+{{play "strings/encoding.go" `/const/` `/}/`}}
 
 Run it to see that it performs the same.
 The `for` `range` loop and `DecodeRuneInString` are defined to produce
diff --git a/blog/_content/strings/basic.go b/go.dev/_content/blog/strings/basic.go
similarity index 100%
rename from blog/_content/strings/basic.go
rename to go.dev/_content/blog/strings/basic.go
diff --git a/blog/_content/strings/encoding.go b/go.dev/_content/blog/strings/encoding.go
similarity index 100%
rename from blog/_content/strings/encoding.go
rename to go.dev/_content/blog/strings/encoding.go
diff --git a/blog/_content/strings/range.go b/go.dev/_content/blog/strings/range.go
similarity index 100%
rename from blog/_content/strings/range.go
rename to go.dev/_content/blog/strings/range.go
diff --git a/blog/_content/strings/utf8.go b/go.dev/_content/blog/strings/utf8.go
similarity index 100%
rename from blog/_content/strings/utf8.go
rename to go.dev/_content/blog/strings/utf8.go
diff --git a/blog/_content/subtests.article b/go.dev/_content/blog/subtests.md
similarity index 96%
rename from blog/_content/subtests.article
rename to go.dev/_content/blog/subtests.md
index ec3dffe..e88e124 100644
--- a/blog/_content/subtests.article
+++ b/go.dev/_content/blog/subtests.md
@@ -1,9 +1,16 @@
-# Using Subtests and Sub-benchmarks
-3 Oct 2016
-Tags: testing, hierarchy, table-driven, subtests, sub-benchmarks
-Summary: How to use Go 1.7's new subtests and sub-benchmarks.
-
-Marcel van Lohuizen
+---
+title: Using Subtests and Sub-benchmarks
+date: 2016-10-03
+by:
+- Marcel van Lohuizen
+tags:
+- testing
+- hierarchy
+- table-driven
+- subtests
+- sub-benchmarks
+summary: How to use Go 1.7's new subtests and sub-benchmarks.
+---
 
 ## Introduction
 
@@ -60,6 +67,7 @@
 For instance, before 1.7 the `strconv` package's benchmarks for `AppendFloat`
 looked something like this:
 
+{{raw `
 	func benchmarkAppendFloat(b *testing.B, f float64, fmt byte, prec, bitSize int) {
 		dst := make([]byte, 30)
 		b.ResetTimer() // Overkill here, but for illustrative purposes.
@@ -74,10 +82,12 @@
 	func BenchmarkAppendFloatNegExp(b *testing.B)  { benchmarkAppendFloat(b, -5.11e-95, 'g', -1, 64) }
 	func BenchmarkAppendFloatBig(b *testing.B)     { benchmarkAppendFloat(b, 123456789123456789123456789, 'g', -1, 64) }
 	...
+`}}
 
 Using the `Run` method available in Go 1.7, the same set of benchmarks is now
 expressed as a single top-level benchmark:
 
+{{raw `
 	func BenchmarkAppendFloat(b *testing.B) {
 		benchmarks := []struct{
 			name    string
@@ -102,6 +112,7 @@
 			})
 		}
 	}
+`}}
 
 Each invocation of the `Run` method creates a separate benchmark.
 An enclosing benchmark function that calls a `Run` method is only run once and
@@ -239,6 +250,7 @@
 
 Subtests and sub-benchmarks can be used to manage common setup and tear-down code:
 
+{{raw `
 	func TestFoo(t *testing.T) {
 		// <setup code>
 		t.Run("A=1", func(t *testing.T) { ... })
@@ -250,6 +262,7 @@
 		})
 		// <tear-down code>
 	}
+`}}
 
 The setup and tear-down code will run if any of the enclosed subtests are run
 and will run at most once.
@@ -311,6 +324,7 @@
 The same technique can be used to clean up after a group of parallel tests
 that share common resources:
 
+{{raw `
 	func TestTeardownParallel(t *testing.T) {
 		// <setup code>
 		// This Run will not return until its parallel subtests complete.
@@ -321,6 +335,7 @@
 		})
 		// <tear-down code>
 	}
+`}}
 
 The behavior of waiting on a group of parallel tests is identical to that
 of the previous example.
diff --git a/blog/_content/survey2011.article b/go.dev/_content/blog/survey2011.md
similarity index 78%
rename from blog/_content/survey2011.article
rename to go.dev/_content/blog/survey2011.md
index ce28b10..8bc295a 100644
--- a/blog/_content/survey2011.article
+++ b/go.dev/_content/blog/survey2011.md
@@ -1,12 +1,13 @@
-# Getting to know the Go community
-21 Dec 2011
-Tags: community
-Summary: Please take a Gopher Survey. We want to hear from you!
-OldURL: /getting-to-know-go-community
+---
+title: Getting to know the Go community
+date: 2011-12-21
+by:
+- Andrew Gerrand
+tags:
+- community
+summary: Please take a Gopher Survey. We want to hear from you!
+---
 
-Andrew Gerrand
-
-##
 
 Over the past couple of years Go has attracted a lot of users and contributors,
 and I've had a great time meeting and talking with many of you.
diff --git a/blog/_content/survey2016-results.article b/go.dev/_content/blog/survey2016-results.md
similarity index 92%
rename from blog/_content/survey2016-results.article
rename to go.dev/_content/blog/survey2016-results.md
index 2b1f21b..00fe284 100644
--- a/blog/_content/survey2016-results.article
+++ b/go.dev/_content/blog/survey2016-results.md
@@ -1,10 +1,13 @@
-# Go 2016 Survey Results
-6 Mar 2017
-Tags: survey, community
-Summary: What we learned from the December 2017 Go User Survey.
-
-Steve Francia, for the Go team
-spf@golang.org
+---
+title: Go 2016 Survey Results
+date: 2017-03-06
+by:
+- Steve Francia, for the Go team
+tags:
+- survey
+- community
+summary: What we learned from the December 2017 Go User Survey.
+---
 
 ## Thank you
 
@@ -33,7 +36,7 @@
 Python (22%), JavaScript (10%), C (9%), Java (9%), and Ruby (7%).
 Go is clearly attracting many programmers from dynamic languages.
 
-.html survey2016/background.html
+{{raw (file "survey2016/background.html")}}
 
 ## Go usage
 
@@ -59,13 +62,13 @@
 
 Some representative common feedback, paraphrased for confidentiality:
 
-.html survey2016/quotes.html
+{{raw (file "survey2016/quotes.html")}}
 
 We appreciate the feedback given to identify these challenges faced by our users and community.
 In 2017 we are focusing on addressing these issues and hope to make as many significant improvements as we can.
 We welcome suggestions and contributions from the community in making these challenges into strengths for Go.
 
-.html survey2016/usage.html
+{{raw (file "survey2016/usage.html")}}
 
 ## Development and deployment
 
@@ -77,7 +80,7 @@
 
 Go deployment is roughly evenly split between privately managed servers and hosted cloud servers.
 
-.html survey2016/dev.html
+{{raw (file "survey2016/dev.html")}}
 
 ## Working Effectively
 
@@ -102,7 +105,7 @@
 The primary sources for finding answers to Go questions are the Go web site,
 Stack Overflow, and reading source code directly.
 
-.html survey2016/effective.html
+{{raw (file "survey2016/effective.html")}}
 
 ## The Go Project
 
@@ -122,7 +125,7 @@
 who are aren’t comfortable reaching out that the Go project leadership is listening.
 Throughout 2017 we will be exploring new ways to engage with users to better understand their needs.
 
-.html survey2016/project.html
+{{raw (file "survey2016/project.html")}}
 
 ## Community
 
@@ -146,4 +149,4 @@
 The final question on the survey was just for fun: what’s your favorite Go keyword?
 Perhaps unsurprisingly, the most popular response was `go`, followed by `defer`, `func`, `interface`, and `select`.
 
-.html survey2016/community.html
+{{raw (file "survey2016/community.html")}}
diff --git a/blog/_content/survey2016.article b/go.dev/_content/blog/survey2016.md
similarity index 90%
rename from blog/_content/survey2016.article
rename to go.dev/_content/blog/survey2016.md
index 698fbb7..2300dbd 100644
--- a/blog/_content/survey2016.article
+++ b/go.dev/_content/blog/survey2016.md
@@ -1,10 +1,13 @@
-# Participate in the 2016 Go User Survey and Company Questionnaire
-13 Dec 2016
-Tags: survey, community
-Summary: Please take the 2016 Go User Survey and Company Questionnaire. We want to hear from you!
-
-Steve Francia
-spf@golang.org
+---
+title: Participate in the 2016 Go User Survey and Company Questionnaire
+date: 2016-12-13
+by:
+- Steve Francia
+tags:
+- survey
+- community
+summary: Please take the 2016 Go User Survey and Company Questionnaire. We want to hear from you!
+---
 
 ## The Go project wants to hear from you!
 
diff --git a/blog/_content/survey2016/README b/go.dev/_content/blog/survey2016/README
similarity index 100%
rename from blog/_content/survey2016/README
rename to go.dev/_content/blog/survey2016/README
diff --git a/blog/_content/survey2016/aboutme.svg b/go.dev/_content/blog/survey2016/aboutme.svg
similarity index 100%
rename from blog/_content/survey2016/aboutme.svg
rename to go.dev/_content/blog/survey2016/aboutme.svg
diff --git a/blog/_content/survey2016/adequate.svg b/go.dev/_content/blog/survey2016/adequate.svg
similarity index 100%
rename from blog/_content/survey2016/adequate.svg
rename to go.dev/_content/blog/survey2016/adequate.svg
diff --git a/blog/_content/survey2016/agree6.svg b/go.dev/_content/blog/survey2016/agree6.svg
similarity index 100%
rename from blog/_content/survey2016/agree6.svg
rename to go.dev/_content/blog/survey2016/agree6.svg
diff --git a/blog/_content/survey2016/answers.svg b/go.dev/_content/blog/survey2016/answers.svg
similarity index 100%
rename from blog/_content/survey2016/answers.svg
rename to go.dev/_content/blog/survey2016/answers.svg
diff --git a/blog/_content/survey2016/areas.svg b/go.dev/_content/blog/survey2016/areas.svg
similarity index 100%
rename from blog/_content/survey2016/areas.svg
rename to go.dev/_content/blog/survey2016/areas.svg
diff --git a/blog/_content/survey2016/attend.svg b/go.dev/_content/blog/survey2016/attend.svg
similarity index 100%
rename from blog/_content/survey2016/attend.svg
rename to go.dev/_content/blog/survey2016/attend.svg
diff --git a/blog/_content/survey2016/background.html b/go.dev/_content/blog/survey2016/background.html
similarity index 100%
rename from blog/_content/survey2016/background.html
rename to go.dev/_content/blog/survey2016/background.html
diff --git a/blog/_content/survey2016/challenge.svg b/go.dev/_content/blog/survey2016/challenge.svg
similarity index 100%
rename from blog/_content/survey2016/challenge.svg
rename to go.dev/_content/blog/survey2016/challenge.svg
diff --git a/blog/_content/survey2016/challenge2.svg b/go.dev/_content/blog/survey2016/challenge2.svg
similarity index 100%
rename from blog/_content/survey2016/challenge2.svg
rename to go.dev/_content/blog/survey2016/challenge2.svg
diff --git a/blog/_content/survey2016/community.html b/go.dev/_content/blog/survey2016/community.html
similarity index 100%
rename from blog/_content/survey2016/community.html
rename to go.dev/_content/blog/survey2016/community.html
diff --git a/blog/_content/survey2016/contribute1.svg b/go.dev/_content/blog/survey2016/contribute1.svg
similarity index 100%
rename from blog/_content/survey2016/contribute1.svg
rename to go.dev/_content/blog/survey2016/contribute1.svg
diff --git a/blog/_content/survey2016/contribute2.svg b/go.dev/_content/blog/survey2016/contribute2.svg
similarity index 100%
rename from blog/_content/survey2016/contribute2.svg
rename to go.dev/_content/blog/survey2016/contribute2.svg
diff --git a/blog/_content/survey2016/country.svg b/go.dev/_content/blog/survey2016/country.svg
similarity index 100%
rename from blog/_content/survey2016/country.svg
rename to go.dev/_content/blog/survey2016/country.svg
diff --git a/blog/_content/survey2016/deploy.svg b/go.dev/_content/blog/survey2016/deploy.svg
similarity index 100%
rename from blog/_content/survey2016/deploy.svg
rename to go.dev/_content/blog/survey2016/deploy.svg
diff --git a/blog/_content/survey2016/dev.html b/go.dev/_content/blog/survey2016/dev.html
similarity index 100%
rename from blog/_content/survey2016/dev.html
rename to go.dev/_content/blog/survey2016/dev.html
diff --git a/blog/_content/survey2016/docs.svg b/go.dev/_content/blog/survey2016/docs.svg
similarity index 100%
rename from blog/_content/survey2016/docs.svg
rename to go.dev/_content/blog/survey2016/docs.svg
diff --git a/blog/_content/survey2016/ed-feature.svg b/go.dev/_content/blog/survey2016/ed-feature.svg
similarity index 100%
rename from blog/_content/survey2016/ed-feature.svg
rename to go.dev/_content/blog/survey2016/ed-feature.svg
diff --git a/blog/_content/survey2016/ed-satisfy.svg b/go.dev/_content/blog/survey2016/ed-satisfy.svg
similarity index 100%
rename from blog/_content/survey2016/ed-satisfy.svg
rename to go.dev/_content/blog/survey2016/ed-satisfy.svg
diff --git a/blog/_content/survey2016/ed.svg b/go.dev/_content/blog/survey2016/ed.svg
similarity index 100%
rename from blog/_content/survey2016/ed.svg
rename to go.dev/_content/blog/survey2016/ed.svg
diff --git a/blog/_content/survey2016/effective.html b/go.dev/_content/blog/survey2016/effective.html
similarity index 100%
rename from blog/_content/survey2016/effective.html
rename to go.dev/_content/blog/survey2016/effective.html
diff --git a/blog/_content/survey2016/effective.svg b/go.dev/_content/blog/survey2016/effective.svg
similarity index 100%
rename from blog/_content/survey2016/effective.svg
rename to go.dev/_content/blog/survey2016/effective.svg
diff --git a/blog/_content/survey2016/final.svg b/go.dev/_content/blog/survey2016/final.svg
similarity index 100%
rename from blog/_content/survey2016/final.svg
rename to go.dev/_content/blog/survey2016/final.svg
diff --git a/blog/_content/survey2016/howlong.svg b/go.dev/_content/blog/survey2016/howlong.svg
similarity index 100%
rename from blog/_content/survey2016/howlong.svg
rename to go.dev/_content/blog/survey2016/howlong.svg
diff --git a/blog/_content/survey2016/identify.svg b/go.dev/_content/blog/survey2016/identify.svg
similarity index 100%
rename from blog/_content/survey2016/identify.svg
rename to go.dev/_content/blog/survey2016/identify.svg
diff --git a/blog/_content/survey2016/improve.svg b/go.dev/_content/blog/survey2016/improve.svg
similarity index 100%
rename from blog/_content/survey2016/improve.svg
rename to go.dev/_content/blog/survey2016/improve.svg
diff --git a/blog/_content/survey2016/keyword.svg b/go.dev/_content/blog/survey2016/keyword.svg
similarity index 100%
rename from blog/_content/survey2016/keyword.svg
rename to go.dev/_content/blog/survey2016/keyword.svg
diff --git a/blog/_content/survey2016/lang-expertise.svg b/go.dev/_content/blog/survey2016/lang-expertise.svg
similarity index 100%
rename from blog/_content/survey2016/lang-expertise.svg
rename to go.dev/_content/blog/survey2016/lang-expertise.svg
diff --git a/blog/_content/survey2016/lang-preference.svg b/go.dev/_content/blog/survey2016/lang-preference.svg
similarity index 100%
rename from blog/_content/survey2016/lang-preference.svg
rename to go.dev/_content/blog/survey2016/lang-preference.svg
diff --git a/blog/_content/survey2016/library.svg b/go.dev/_content/blog/survey2016/library.svg
similarity index 100%
rename from blog/_content/survey2016/library.svg
rename to go.dev/_content/blog/survey2016/library.svg
diff --git a/blog/_content/survey2016/like.svg b/go.dev/_content/blog/survey2016/like.svg
similarity index 100%
rename from blog/_content/survey2016/like.svg
rename to go.dev/_content/blog/survey2016/like.svg
diff --git a/blog/_content/survey2016/mkhtml.go b/go.dev/_content/blog/survey2016/mkhtml.go
similarity index 100%
rename from blog/_content/survey2016/mkhtml.go
rename to go.dev/_content/blog/survey2016/mkhtml.go
diff --git a/blog/_content/survey2016/news.svg b/go.dev/_content/blog/survey2016/news.svg
similarity index 100%
rename from blog/_content/survey2016/news.svg
rename to go.dev/_content/blog/survey2016/news.svg
diff --git a/blog/_content/survey2016/project.html b/go.dev/_content/blog/survey2016/project.html
similarity index 100%
rename from blog/_content/survey2016/project.html
rename to go.dev/_content/blog/survey2016/project.html
diff --git a/blog/_content/survey2016/quotes.html b/go.dev/_content/blog/survey2016/quotes.html
similarity index 100%
rename from blog/_content/survey2016/quotes.html
rename to go.dev/_content/blog/survey2016/quotes.html
diff --git a/blog/_content/survey2016/recommend.svg b/go.dev/_content/blog/survey2016/recommend.svg
similarity index 100%
rename from blog/_content/survey2016/recommend.svg
rename to go.dev/_content/blog/survey2016/recommend.svg
diff --git a/blog/_content/survey2016/system.svg b/go.dev/_content/blog/survey2016/system.svg
similarity index 100%
rename from blog/_content/survey2016/system.svg
rename to go.dev/_content/blog/survey2016/system.svg
diff --git a/blog/_content/survey2016/usage.html b/go.dev/_content/blog/survey2016/usage.html
similarity index 100%
rename from blog/_content/survey2016/usage.html
rename to go.dev/_content/blog/survey2016/usage.html
diff --git a/blog/_content/survey2016/uses.svg b/go.dev/_content/blog/survey2016/uses.svg
similarity index 100%
rename from blog/_content/survey2016/uses.svg
rename to go.dev/_content/blog/survey2016/uses.svg
diff --git a/blog/_content/survey2016/welcome.svg b/go.dev/_content/blog/survey2016/welcome.svg
similarity index 100%
rename from blog/_content/survey2016/welcome.svg
rename to go.dev/_content/blog/survey2016/welcome.svg
diff --git a/blog/_content/survey2016/welcoming.svg b/go.dev/_content/blog/survey2016/welcoming.svg
similarity index 100%
rename from blog/_content/survey2016/welcoming.svg
rename to go.dev/_content/blog/survey2016/welcoming.svg
diff --git a/blog/_content/survey2016/when.svg b/go.dev/_content/blog/survey2016/when.svg
similarity index 100%
rename from blog/_content/survey2016/when.svg
rename to go.dev/_content/blog/survey2016/when.svg
diff --git a/blog/_content/survey2016/why-not-text.svg b/go.dev/_content/blog/survey2016/why-not-text.svg
similarity index 100%
rename from blog/_content/survey2016/why-not-text.svg
rename to go.dev/_content/blog/survey2016/why-not-text.svg
diff --git a/blog/_content/survey2016/why-not.svg b/go.dev/_content/blog/survey2016/why-not.svg
similarity index 100%
rename from blog/_content/survey2016/why-not.svg
rename to go.dev/_content/blog/survey2016/why-not.svg
diff --git a/blog/_content/survey2017-results.article b/go.dev/_content/blog/survey2017-results.md
similarity index 94%
rename from blog/_content/survey2017-results.article
rename to go.dev/_content/blog/survey2017-results.md
index 771f1cb..1d2bc14 100644
--- a/blog/_content/survey2017-results.article
+++ b/go.dev/_content/blog/survey2017-results.md
@@ -1,10 +1,13 @@
-# Go 2017 Survey Results
-26 Feb 2018
-Tags: survey, community
-Summary: What we learned from the December 2017 Go User Survey.
-
-Steve Francia
-spf@golang.org
+---
+title: Go 2017 Survey Results
+date: 2018-02-26
+by:
+- Steve Francia
+tags:
+- survey
+- community
+summary: What we learned from the December 2017 Go User Survey.
+---
 
 ## Thank you
 
@@ -44,7 +47,7 @@
 developers, the order of language rankings remains quite consistent with last
 year.
 
-.html survey2017/background.html
+{{raw (file "survey2017/background.html")}}
 
 ## Go usage
 
@@ -75,7 +78,7 @@
 a decreased percentage who identified "Go not being an appropriate fit". Other
 than these changes, the list remains consistent with last year.
 
-.html survey2017/usage.html
+{{raw (file "survey2017/usage.html")}}
 
 ## Development and deployment
 
@@ -98,7 +101,7 @@
 hosted cloud servers. For Go applications, Google Cloud services saw significant
 increase over 2016. For Non-Go applications, AWS Lambda saw the largest increase in use.
 
-.html survey2017/dev.html
+{{raw (file "survey2017/dev.html")}}
 
 ## Working Effectively
 
@@ -121,7 +124,7 @@
 Twitter; like last year, there may be some bias here since these are also how
 the survey was announced.
 
-.html survey2017/effective.html
+{{raw (file "survey2017/effective.html")}}
 
 ## The Go Project
 
@@ -145,7 +148,7 @@
 with users in 2017 and while progress was made, we are still working on making these
 solutions scalable for our growing community.
 
-.html survey2017/project.html
+{{raw (file "survey2017/project.html")}}
 
 ## Community
 
@@ -185,7 +188,7 @@
 keyword? Perhaps unsurprisingly, the most popular response was `go`, followed by
 `defer`, `func`, `interface`, and `select`, unchanged from last year.
 
-.html survey2017/community.html
+{{raw (file "survey2017/community.html")}}
 
 Finally, on behalf of the entire Go project, we are grateful for everyone who
 has contributed to our project, whether by being a part of our great community,
diff --git a/blog/_content/survey2017.article b/go.dev/_content/blog/survey2017.md
similarity index 87%
rename from blog/_content/survey2017.article
rename to go.dev/_content/blog/survey2017.md
index 84e44bd..f55d5bc 100644
--- a/blog/_content/survey2017.article
+++ b/go.dev/_content/blog/survey2017.md
@@ -1,10 +1,13 @@
-# Participate in the 2017 Go User Survey
-16 Nov 2017
-Tags: survey, community
-Summary: Please take the 2017 Go User Survey. We want to hear from you!
-
-Steve Francia
-spf@golang.org
+---
+title: Participate in the 2017 Go User Survey
+date: 2017-11-16
+by:
+- Steve Francia
+tags:
+- survey
+- community
+summary: Please take the 2017 Go User Survey. We want to hear from you!
+---
 
 ## The Go project wants to hear from you (again)!
 
diff --git a/blog/_content/survey2017/about-me-comp.svg b/go.dev/_content/blog/survey2017/about-me-comp.svg
similarity index 100%
rename from blog/_content/survey2017/about-me-comp.svg
rename to go.dev/_content/blog/survey2017/about-me-comp.svg
diff --git a/blog/_content/survey2017/about-me.svg b/go.dev/_content/blog/survey2017/about-me.svg
similarity index 100%
rename from blog/_content/survey2017/about-me.svg
rename to go.dev/_content/blog/survey2017/about-me.svg
diff --git a/blog/_content/survey2017/access.svg b/go.dev/_content/blog/survey2017/access.svg
similarity index 100%
rename from blog/_content/survey2017/access.svg
rename to go.dev/_content/blog/survey2017/access.svg
diff --git a/blog/_content/survey2017/agree-community.svg b/go.dev/_content/blog/survey2017/agree-community.svg
similarity index 100%
rename from blog/_content/survey2017/agree-community.svg
rename to go.dev/_content/blog/survey2017/agree-community.svg
diff --git a/blog/_content/survey2017/agree-diagnose.svg b/go.dev/_content/blog/survey2017/agree-diagnose.svg
similarity index 100%
rename from blog/_content/survey2017/agree-diagnose.svg
rename to go.dev/_content/blog/survey2017/agree-diagnose.svg
diff --git a/blog/_content/survey2017/agree-practices.svg b/go.dev/_content/blog/survey2017/agree-practices.svg
similarity index 100%
rename from blog/_content/survey2017/agree-practices.svg
rename to go.dev/_content/blog/survey2017/agree-practices.svg
diff --git a/blog/_content/survey2017/agree-project.svg b/go.dev/_content/blog/survey2017/agree-project.svg
similarity index 100%
rename from blog/_content/survey2017/agree-project.svg
rename to go.dev/_content/blog/survey2017/agree-project.svg
diff --git a/blog/_content/survey2017/agree-work-well.svg b/go.dev/_content/blog/survey2017/agree-work-well.svg
similarity index 100%
rename from blog/_content/survey2017/agree-work-well.svg
rename to go.dev/_content/blog/survey2017/agree-work-well.svg
diff --git a/blog/_content/survey2017/answers.svg b/go.dev/_content/blog/survey2017/answers.svg
similarity index 100%
rename from blog/_content/survey2017/answers.svg
rename to go.dev/_content/blog/survey2017/answers.svg
diff --git a/blog/_content/survey2017/area-comp.svg b/go.dev/_content/blog/survey2017/area-comp.svg
similarity index 100%
rename from blog/_content/survey2017/area-comp.svg
rename to go.dev/_content/blog/survey2017/area-comp.svg
diff --git a/blog/_content/survey2017/area.svg b/go.dev/_content/blog/survey2017/area.svg
similarity index 100%
rename from blog/_content/survey2017/area.svg
rename to go.dev/_content/blog/survey2017/area.svg
diff --git a/blog/_content/survey2017/background.html b/go.dev/_content/blog/survey2017/background.html
similarity index 100%
rename from blog/_content/survey2017/background.html
rename to go.dev/_content/blog/survey2017/background.html
diff --git a/blog/_content/survey2017/challenge.svg b/go.dev/_content/blog/survey2017/challenge.svg
similarity index 100%
rename from blog/_content/survey2017/challenge.svg
rename to go.dev/_content/blog/survey2017/challenge.svg
diff --git a/blog/_content/survey2017/community.html b/go.dev/_content/blog/survey2017/community.html
similarity index 100%
rename from blog/_content/survey2017/community.html
rename to go.dev/_content/blog/survey2017/community.html
diff --git a/blog/_content/survey2017/community.svg b/go.dev/_content/blog/survey2017/community.svg
similarity index 100%
rename from blog/_content/survey2017/community.svg
rename to go.dev/_content/blog/survey2017/community.svg
diff --git a/blog/_content/survey2017/contrib.svg b/go.dev/_content/blog/survey2017/contrib.svg
similarity index 100%
rename from blog/_content/survey2017/contrib.svg
rename to go.dev/_content/blog/survey2017/contrib.svg
diff --git a/blog/_content/survey2017/country.svg b/go.dev/_content/blog/survey2017/country.svg
similarity index 100%
rename from blog/_content/survey2017/country.svg
rename to go.dev/_content/blog/survey2017/country.svg
diff --git a/blog/_content/survey2017/deploy-go-comp.svg b/go.dev/_content/blog/survey2017/deploy-go-comp.svg
similarity index 100%
rename from blog/_content/survey2017/deploy-go-comp.svg
rename to go.dev/_content/blog/survey2017/deploy-go-comp.svg
diff --git a/blog/_content/survey2017/deploy-go.svg b/go.dev/_content/blog/survey2017/deploy-go.svg
similarity index 100%
rename from blog/_content/survey2017/deploy-go.svg
rename to go.dev/_content/blog/survey2017/deploy-go.svg
diff --git a/blog/_content/survey2017/deploy-nongo-comp.svg b/go.dev/_content/blog/survey2017/deploy-nongo-comp.svg
similarity index 100%
rename from blog/_content/survey2017/deploy-nongo-comp.svg
rename to go.dev/_content/blog/survey2017/deploy-nongo-comp.svg
diff --git a/blog/_content/survey2017/deploy-nongo.svg b/go.dev/_content/blog/survey2017/deploy-nongo.svg
similarity index 100%
rename from blog/_content/survey2017/deploy-nongo.svg
rename to go.dev/_content/blog/survey2017/deploy-nongo.svg
diff --git a/blog/_content/survey2017/dev.html b/go.dev/_content/blog/survey2017/dev.html
similarity index 100%
rename from blog/_content/survey2017/dev.html
rename to go.dev/_content/blog/survey2017/dev.html
diff --git a/blog/_content/survey2017/editor-comp.svg b/go.dev/_content/blog/survey2017/editor-comp.svg
similarity index 100%
rename from blog/_content/survey2017/editor-comp.svg
rename to go.dev/_content/blog/survey2017/editor-comp.svg
diff --git a/blog/_content/survey2017/editor.svg b/go.dev/_content/blog/survey2017/editor.svg
similarity index 100%
rename from blog/_content/survey2017/editor.svg
rename to go.dev/_content/blog/survey2017/editor.svg
diff --git a/blog/_content/survey2017/effective.html b/go.dev/_content/blog/survey2017/effective.html
similarity index 100%
rename from blog/_content/survey2017/effective.html
rename to go.dev/_content/blog/survey2017/effective.html
diff --git a/blog/_content/survey2017/event.svg b/go.dev/_content/blog/survey2017/event.svg
similarity index 100%
rename from blog/_content/survey2017/event.svg
rename to go.dev/_content/blog/survey2017/event.svg
diff --git a/blog/_content/survey2017/final.svg b/go.dev/_content/blog/survey2017/final.svg
similarity index 100%
rename from blog/_content/survey2017/final.svg
rename to go.dev/_content/blog/survey2017/final.svg
diff --git a/blog/_content/survey2017/freq.svg b/go.dev/_content/blog/survey2017/freq.svg
similarity index 100%
rename from blog/_content/survey2017/freq.svg
rename to go.dev/_content/blog/survey2017/freq.svg
diff --git a/blog/_content/survey2017/how-long.svg b/go.dev/_content/blog/survey2017/how-long.svg
similarity index 100%
rename from blog/_content/survey2017/how-long.svg
rename to go.dev/_content/blog/survey2017/how-long.svg
diff --git a/blog/_content/survey2017/identify.svg b/go.dev/_content/blog/survey2017/identify.svg
similarity index 100%
rename from blog/_content/survey2017/identify.svg
rename to go.dev/_content/blog/survey2017/identify.svg
diff --git a/blog/_content/survey2017/implemented.svg b/go.dev/_content/blog/survey2017/implemented.svg
similarity index 100%
rename from blog/_content/survey2017/implemented.svg
rename to go.dev/_content/blog/survey2017/implemented.svg
diff --git a/blog/_content/survey2017/keyword.svg b/go.dev/_content/blog/survey2017/keyword.svg
similarity index 100%
rename from blog/_content/survey2017/keyword.svg
rename to go.dev/_content/blog/survey2017/keyword.svg
diff --git a/blog/_content/survey2017/lang-exp.svg b/go.dev/_content/blog/survey2017/lang-exp.svg
similarity index 100%
rename from blog/_content/survey2017/lang-exp.svg
rename to go.dev/_content/blog/survey2017/lang-exp.svg
diff --git a/blog/_content/survey2017/lang-pref.svg b/go.dev/_content/blog/survey2017/lang-pref.svg
similarity index 100%
rename from blog/_content/survey2017/lang-pref.svg
rename to go.dev/_content/blog/survey2017/lang-pref.svg
diff --git a/blog/_content/survey2017/last-year.svg b/go.dev/_content/blog/survey2017/last-year.svg
similarity index 100%
rename from blog/_content/survey2017/last-year.svg
rename to go.dev/_content/blog/survey2017/last-year.svg
diff --git a/blog/_content/survey2017/libraries.svg b/go.dev/_content/blog/survey2017/libraries.svg
similarity index 100%
rename from blog/_content/survey2017/libraries.svg
rename to go.dev/_content/blog/survey2017/libraries.svg
diff --git a/blog/_content/survey2017/mkhtml.go b/go.dev/_content/blog/survey2017/mkhtml.go
similarity index 100%
rename from blog/_content/survey2017/mkhtml.go
rename to go.dev/_content/blog/survey2017/mkhtml.go
diff --git a/blog/_content/survey2017/news.svg b/go.dev/_content/blog/survey2017/news.svg
similarity index 100%
rename from blog/_content/survey2017/news.svg
rename to go.dev/_content/blog/survey2017/news.svg
diff --git a/blog/_content/survey2017/open-source.svg b/go.dev/_content/blog/survey2017/open-source.svg
similarity index 100%
rename from blog/_content/survey2017/open-source.svg
rename to go.dev/_content/blog/survey2017/open-source.svg
diff --git a/blog/_content/survey2017/os.svg b/go.dev/_content/blog/survey2017/os.svg
similarity index 100%
rename from blog/_content/survey2017/os.svg
rename to go.dev/_content/blog/survey2017/os.svg
diff --git a/blog/_content/survey2017/project.html b/go.dev/_content/blog/survey2017/project.html
similarity index 100%
rename from blog/_content/survey2017/project.html
rename to go.dev/_content/blog/survey2017/project.html
diff --git a/blog/_content/survey2017/sat-editor.svg b/go.dev/_content/blog/survey2017/sat-editor.svg
similarity index 100%
rename from blog/_content/survey2017/sat-editor.svg
rename to go.dev/_content/blog/survey2017/sat-editor.svg
diff --git a/blog/_content/survey2017/usage.html b/go.dev/_content/blog/survey2017/usage.html
similarity index 100%
rename from blog/_content/survey2017/usage.html
rename to go.dev/_content/blog/survey2017/usage.html
diff --git a/blog/_content/survey2017/uses-comp.svg b/go.dev/_content/blog/survey2017/uses-comp.svg
similarity index 100%
rename from blog/_content/survey2017/uses-comp.svg
rename to go.dev/_content/blog/survey2017/uses-comp.svg
diff --git a/blog/_content/survey2017/uses.svg b/go.dev/_content/blog/survey2017/uses.svg
similarity index 100%
rename from blog/_content/survey2017/uses.svg
rename to go.dev/_content/blog/survey2017/uses.svg
diff --git a/blog/_content/survey2017/why-not-comp.svg b/go.dev/_content/blog/survey2017/why-not-comp.svg
similarity index 100%
rename from blog/_content/survey2017/why-not-comp.svg
rename to go.dev/_content/blog/survey2017/why-not-comp.svg
diff --git a/blog/_content/survey2017/why-not.svg b/go.dev/_content/blog/survey2017/why-not.svg
similarity index 100%
rename from blog/_content/survey2017/why-not.svg
rename to go.dev/_content/blog/survey2017/why-not.svg
diff --git a/blog/_content/survey2018-company.article b/go.dev/_content/blog/survey2018-company.md
similarity index 86%
rename from blog/_content/survey2018-company.article
rename to go.dev/_content/blog/survey2018-company.md
index aa9acbe..70d6481 100644
--- a/blog/_content/survey2018-company.article
+++ b/go.dev/_content/blog/survey2018-company.md
@@ -1,11 +1,13 @@
-# Participate in the 2018 Go Company Questionnaire
-4 Oct 2018
-Tags: survey, community
-Summary: Please take the 2018 Go Company Questionnaire.
-OldURL: /company-questionnaire2018
-
-Ran Tao, Steve Francia
-spf@golang.org
+---
+title: Participate in the 2018 Go Company Questionnaire
+date: 2018-10-04
+by:
+- Ran Tao, Steve Francia
+tags:
+- survey
+- community
+summary: Please take the 2018 Go Company Questionnaire.
+---
 
 ## The Go project wants to hear from you!
 
diff --git a/blog/_content/survey2018-results.article b/go.dev/_content/blog/survey2018-results.md
similarity index 93%
rename from blog/_content/survey2018-results.article
rename to go.dev/_content/blog/survey2018-results.md
index de95d0b..913cdec 100644
--- a/blog/_content/survey2018-results.article
+++ b/go.dev/_content/blog/survey2018-results.md
@@ -1,10 +1,13 @@
-# Go 2018 Survey Results
-28 Mar 2019
-Tags: survey, community
-Summary: What we learned from the December 2018 Go User Survey.
-
-Todd Kulesza, Steve Francia
-tkulesza@google.com, spf@golang.org
+---
+title: Go 2018 Survey Results
+date: 2019-03-28
+by:
+- Todd Kulesza, Steve Francia
+tags:
+- survey
+- community
+summary: What we learned from the December 2018 Go User Survey.
+---
 
 ## Thank you
 
@@ -61,8 +64,8 @@
 software development at a consistent pace,
 and that Go's general popularity with developers remains strong.
 
-.image survey2018/fig1.svg _ 600
-.image survey2018/fig2.svg _ 600
+{{image "survey2018/fig1.svg" 600}}
+{{image "survey2018/fig2.svg" 600}}
 
 To better understand where developers use Go,
 we broke responses down into three groups:
@@ -81,7 +84,7 @@
 see section _Attitudes towards Go_ below) Go is the top language they'd
 prefer to use for these non-work-related projects.
 
-.image survey2018/fig4.svg _ 600
+{{image "survey2018/fig4.svg" 600}}
 
 When asked how long they've been using Go,
 participants' answers are strongly trending upward over time,
@@ -93,7 +96,7 @@
 as this suggests that developers are not dropping out of the ecosystem after
 initially learning the language.
 
-.image survey2018/fig5.svg _ 600
+{{image "survey2018/fig5.svg" 600}}
 
 As in prior years, Go ranks at the top of respondents' preferred languages
 and languages in which they have expertise.
@@ -124,8 +127,8 @@
     This data is corroborated by [Stack Overflow's 2018 developer survey](https://insights.stackoverflow.com/survey/2018/#most-loved-dreaded-and-wanted),
     which also found Rust, Kotlin, and Go to be among the most-preferred programming languages.
 
-.image survey2018/fig6.svg _ 600
-.image survey2018/fig7.svg _ 600
+{{image "survey2018/fig6.svg" 600}}
+{{image "survey2018/fig7.svg" 600}}
 
 <p class="note">
     <i>Reading the data</i>: Participants could rank their top 5 languages. The color coding starts with dark blue for the top rank and lightens for each successive rank. These charts are sorted by the percentage of participants who ranked each language as their top choice.
@@ -145,7 +148,7 @@
 suggesting that respondents are adopting Go for a wider variety of projects,
 rather than shifting usage from one domain to another.
 
-.image survey2018/fig8.svg _ 600
+{{image "survey2018/fig8.svg" 600}}
 
 Since 2016, the top two uses of Go have been writing API/RPC services and
 developing CLI applications.
@@ -160,7 +163,7 @@
 Another year-over-year trend suggests that automation is also a growing area for Go,
 with 38% of respondents now using Go for scripts and automation tasks (up from 31% in 2016).
 
-.image survey2018/fig9.svg _ 600
+{{image "survey2018/fig9.svg" 600}}
 
 To better understand the contexts in which developers are using Go,
 we added a question about Go adoption across different industries.
@@ -174,7 +177,7 @@
 adoption across industries to better understand developer needs outside
 of technology companies.
 
-.image survey2018/fig10.svg _ 600
+{{image "survey2018/fig10.svg" 600}}
 
 ## Attitudes towards Go
 
@@ -187,7 +190,7 @@
 Our 2018 score is 61 (68% promoters - 7% detractors) and will serve as a
 baseline to help us gauge community sentiment towards the Go ecosystem over time.
 
-.image survey2018/fig11.svg _ 600
+{{image "survey2018/fig11.svg" 600}}
 
 In addition to NPS, we asked several questions about developer satisfaction with Go.
 Overall, survey respondents indicated a high level of satisfaction,
@@ -202,7 +205,7 @@
 to "_Overall, I'm happy with Go_",
 so those results are not directly comparable.)
 
-.image survey2018/fig12.svg _ 600
+{{image "survey2018/fig12.svg" 600}}
 
 Given the strong sentiment towards preferring Go for future development,
 we want to understand what prevents developers from doing so.
@@ -229,8 +232,8 @@
     people who have not tried Go that they would find it efficient.",
     "Hard to build richer abstractions (want generics)")
 
-.image survey2018/fig13.svg _ 600
-.image survey2018/fig14.svg _ 600
+{{image "survey2018/fig13.svg" 600}}
+{{image "survey2018/fig14.svg" 600}}
 
 This year we added several questions about developer satisfaction with different aspects of Go.
 Survey respondents were very satisfied with Go applications' CPU performance (46:1,
@@ -258,8 +261,8 @@
 We plan to investigate how developers debug Go applications in more depth this year,
 with a goal of improving the overall debugging experience for Go developers.
 
-.image survey2018/fig15.svg _ 600
-.image survey2018/fig29.svg _ 600
+{{image "survey2018/fig15.svg" 600}}
+{{image "survey2018/fig29.svg" 600}}
 
 ## Development environments
 
@@ -273,7 +276,7 @@
 Overall, 41% of respondents use multiple operating systems for Go development,
 highlighting the cross-platform nature of Go.
 
-.image survey2018/fig16.svg _ 600
+{{image "survey2018/fig16.svg" 600}}
 
 Last year, VS Code edged out Vim as the most popular Go editor among survey respondents.
 This year it significantly expanded its lead to become the preferred editor
@@ -299,8 +302,8 @@
 Other requests include better integration with Go's CLI toolchain,
 better support for modules/packages, and general performance improvements.
 
-.image survey2018/fig17.svg _ 600
-.image survey2018/fig18.svg _ 600
+{{image "survey2018/fig17.svg" 600}}
+{{image "survey2018/fig18.svg" 600}}
 
 This year we also added a question asking which deployment architectures
 are most important to Go developers.
@@ -313,7 +316,7 @@
 there is significant interest in ARM64 (45%),
 WebAssembly (30%), and ARM (22%), but very little interest in other platforms.
 
-.image survey2018/fig19.svg _ 600
+{{image "survey2018/fig19.svg" 600}}
 
 ## Deployments and services
 
@@ -334,7 +337,7 @@
 We also see steady growth in Go deployments to GCP since 2016,
 increasing from 12% → 19% of respondents.
 
-.image survey2018/fig20.svg _ 600
+{{image "survey2018/fig20.svg" 600}}
 
 Perhaps correlated with the decrease in on-prem deployments,
 this year we saw cloud storage become the second-most used service by survey respondents,
@@ -345,7 +348,7 @@
 which ticked up from 61% → 65% of respondents.
 As the below chart shows, service usage increased across the board.
 
-.image survey2018/fig21.svg _ 600
+{{image "survey2018/fig21.svg" 600}}
 
 ## Go community
 
@@ -362,8 +365,8 @@
 In the two charts below, we've grouped sources used by less than < 5% of
 respondents into the "Other" category.
 
-.image survey2018/fig24.svg _ 600
-.image survey2018/fig25.svg _ 600
+{{image "survey2018/fig24.svg" 600}}
+{{image "survey2018/fig25.svg" 600}}
 
 This year, 55% of survey respondents said they have or are interested in
 contributing to the Go community,
@@ -375,8 +378,8 @@
 leadership with questions and feedback" (30% → 25%) and "I am confident
 in the leadership of Go (54% → 46%).
 
-.image survey2018/fig26.svg _ 600
-.image survey2018/fig27.svg _ 600
+{{image "survey2018/fig26.svg" 600}}
+{{image "survey2018/fig27.svg" 600}}
 
 An important aspect of community is helping everyone feel welcome,
 especially people from traditionally under-represented demographics.
@@ -393,7 +396,7 @@
 is at least retaining the same proportions of under-represented members,
 and may even be increasing.
 
-.image survey2018/fig28.svg _ 600
+{{image "survey2018/fig28.svg" 600}}
 
 Maintaining a healthy community is extremely important to the Go project,
 so for the past three years we've been measuring the extent to which developers
@@ -430,8 +433,8 @@
 While it doesn't represent a large percentage of our user base,
 we take this feedback very seriously and are working on improving each area.
 
-.image survey2018/fig22.svg _ 600
-.image survey2018/fig23.svg _ 600
+{{image "survey2018/fig22.svg" 600}}
+{{image "survey2018/fig23.svg" 600}}
 
 ## Conclusion
 
diff --git a/blog/_content/survey2018.article b/go.dev/_content/blog/survey2018.md
similarity index 87%
rename from blog/_content/survey2018.article
rename to go.dev/_content/blog/survey2018.md
index 3e28dc5..9697449 100644
--- a/blog/_content/survey2018.article
+++ b/go.dev/_content/blog/survey2018.md
@@ -1,10 +1,13 @@
-# Participate in the 2018 Go User Survey
-8 Nov 2018
-Tags: survey, community
-Summary: Please take the 2018 Go User Survey. We want to hear from you!
-
-Ran Tao, Steve Francia
-spf@golang.org
+---
+title: Participate in the 2018 Go User Survey
+date: 2018-11-08
+by:
+- Ran Tao, Steve Francia
+tags:
+- survey
+- community
+summary: Please take the 2018 Go User Survey. We want to hear from you!
+---
 
 ## The Go project wants to hear from you, the Go community!
 
diff --git a/blog/_content/survey2018/fig1.svg b/go.dev/_content/blog/survey2018/fig1.svg
similarity index 100%
rename from blog/_content/survey2018/fig1.svg
rename to go.dev/_content/blog/survey2018/fig1.svg
diff --git a/blog/_content/survey2018/fig10.svg b/go.dev/_content/blog/survey2018/fig10.svg
similarity index 100%
rename from blog/_content/survey2018/fig10.svg
rename to go.dev/_content/blog/survey2018/fig10.svg
diff --git a/blog/_content/survey2018/fig11.svg b/go.dev/_content/blog/survey2018/fig11.svg
similarity index 100%
rename from blog/_content/survey2018/fig11.svg
rename to go.dev/_content/blog/survey2018/fig11.svg
diff --git a/blog/_content/survey2018/fig12.svg b/go.dev/_content/blog/survey2018/fig12.svg
similarity index 100%
rename from blog/_content/survey2018/fig12.svg
rename to go.dev/_content/blog/survey2018/fig12.svg
diff --git a/blog/_content/survey2018/fig13.svg b/go.dev/_content/blog/survey2018/fig13.svg
similarity index 100%
rename from blog/_content/survey2018/fig13.svg
rename to go.dev/_content/blog/survey2018/fig13.svg
diff --git a/blog/_content/survey2018/fig14.svg b/go.dev/_content/blog/survey2018/fig14.svg
similarity index 100%
rename from blog/_content/survey2018/fig14.svg
rename to go.dev/_content/blog/survey2018/fig14.svg
diff --git a/blog/_content/survey2018/fig15.svg b/go.dev/_content/blog/survey2018/fig15.svg
similarity index 100%
rename from blog/_content/survey2018/fig15.svg
rename to go.dev/_content/blog/survey2018/fig15.svg
diff --git a/blog/_content/survey2018/fig16.svg b/go.dev/_content/blog/survey2018/fig16.svg
similarity index 100%
rename from blog/_content/survey2018/fig16.svg
rename to go.dev/_content/blog/survey2018/fig16.svg
diff --git a/blog/_content/survey2018/fig17.svg b/go.dev/_content/blog/survey2018/fig17.svg
similarity index 100%
rename from blog/_content/survey2018/fig17.svg
rename to go.dev/_content/blog/survey2018/fig17.svg
diff --git a/blog/_content/survey2018/fig18.svg b/go.dev/_content/blog/survey2018/fig18.svg
similarity index 100%
rename from blog/_content/survey2018/fig18.svg
rename to go.dev/_content/blog/survey2018/fig18.svg
diff --git a/blog/_content/survey2018/fig19.svg b/go.dev/_content/blog/survey2018/fig19.svg
similarity index 100%
rename from blog/_content/survey2018/fig19.svg
rename to go.dev/_content/blog/survey2018/fig19.svg
diff --git a/blog/_content/survey2018/fig2.svg b/go.dev/_content/blog/survey2018/fig2.svg
similarity index 100%
rename from blog/_content/survey2018/fig2.svg
rename to go.dev/_content/blog/survey2018/fig2.svg
diff --git a/blog/_content/survey2018/fig20.svg b/go.dev/_content/blog/survey2018/fig20.svg
similarity index 100%
rename from blog/_content/survey2018/fig20.svg
rename to go.dev/_content/blog/survey2018/fig20.svg
diff --git a/blog/_content/survey2018/fig21.svg b/go.dev/_content/blog/survey2018/fig21.svg
similarity index 100%
rename from blog/_content/survey2018/fig21.svg
rename to go.dev/_content/blog/survey2018/fig21.svg
diff --git a/blog/_content/survey2018/fig22.svg b/go.dev/_content/blog/survey2018/fig22.svg
similarity index 100%
rename from blog/_content/survey2018/fig22.svg
rename to go.dev/_content/blog/survey2018/fig22.svg
diff --git a/blog/_content/survey2018/fig23.svg b/go.dev/_content/blog/survey2018/fig23.svg
similarity index 100%
rename from blog/_content/survey2018/fig23.svg
rename to go.dev/_content/blog/survey2018/fig23.svg
diff --git a/blog/_content/survey2018/fig24.svg b/go.dev/_content/blog/survey2018/fig24.svg
similarity index 100%
rename from blog/_content/survey2018/fig24.svg
rename to go.dev/_content/blog/survey2018/fig24.svg
diff --git a/blog/_content/survey2018/fig25.svg b/go.dev/_content/blog/survey2018/fig25.svg
similarity index 100%
rename from blog/_content/survey2018/fig25.svg
rename to go.dev/_content/blog/survey2018/fig25.svg
diff --git a/blog/_content/survey2018/fig26.svg b/go.dev/_content/blog/survey2018/fig26.svg
similarity index 100%
rename from blog/_content/survey2018/fig26.svg
rename to go.dev/_content/blog/survey2018/fig26.svg
diff --git a/blog/_content/survey2018/fig27.svg b/go.dev/_content/blog/survey2018/fig27.svg
similarity index 100%
rename from blog/_content/survey2018/fig27.svg
rename to go.dev/_content/blog/survey2018/fig27.svg
diff --git a/blog/_content/survey2018/fig28.svg b/go.dev/_content/blog/survey2018/fig28.svg
similarity index 100%
rename from blog/_content/survey2018/fig28.svg
rename to go.dev/_content/blog/survey2018/fig28.svg
diff --git a/blog/_content/survey2018/fig29.svg b/go.dev/_content/blog/survey2018/fig29.svg
similarity index 100%
rename from blog/_content/survey2018/fig29.svg
rename to go.dev/_content/blog/survey2018/fig29.svg
diff --git a/blog/_content/survey2018/fig3.svg b/go.dev/_content/blog/survey2018/fig3.svg
similarity index 100%
rename from blog/_content/survey2018/fig3.svg
rename to go.dev/_content/blog/survey2018/fig3.svg
diff --git a/blog/_content/survey2018/fig4.svg b/go.dev/_content/blog/survey2018/fig4.svg
similarity index 100%
rename from blog/_content/survey2018/fig4.svg
rename to go.dev/_content/blog/survey2018/fig4.svg
diff --git a/blog/_content/survey2018/fig5.svg b/go.dev/_content/blog/survey2018/fig5.svg
similarity index 100%
rename from blog/_content/survey2018/fig5.svg
rename to go.dev/_content/blog/survey2018/fig5.svg
diff --git a/blog/_content/survey2018/fig6.svg b/go.dev/_content/blog/survey2018/fig6.svg
similarity index 100%
rename from blog/_content/survey2018/fig6.svg
rename to go.dev/_content/blog/survey2018/fig6.svg
diff --git a/blog/_content/survey2018/fig7.svg b/go.dev/_content/blog/survey2018/fig7.svg
similarity index 100%
rename from blog/_content/survey2018/fig7.svg
rename to go.dev/_content/blog/survey2018/fig7.svg
diff --git a/blog/_content/survey2018/fig8.svg b/go.dev/_content/blog/survey2018/fig8.svg
similarity index 100%
rename from blog/_content/survey2018/fig8.svg
rename to go.dev/_content/blog/survey2018/fig8.svg
diff --git a/blog/_content/survey2018/fig9.svg b/go.dev/_content/blog/survey2018/fig9.svg
similarity index 100%
rename from blog/_content/survey2018/fig9.svg
rename to go.dev/_content/blog/survey2018/fig9.svg
diff --git a/blog/_content/survey2019-results.article b/go.dev/_content/blog/survey2019-results.md
similarity index 93%
rename from blog/_content/survey2019-results.article
rename to go.dev/_content/blog/survey2019-results.md
index d47c24c..f147b79 100644
--- a/blog/_content/survey2019-results.article
+++ b/go.dev/_content/blog/survey2019-results.md
@@ -1,10 +1,13 @@
-# Go Developer Survey 2019 Results
-20 Apr 2020
-Tags: survey, community
-Summary: An analysis of the results from the 2019 Go Developer Survey.
-
-Todd Kulesza
-tkulesza@google.com
+---
+title: Go Developer Survey 2019 Results
+date: 2020-04-20
+by:
+- Todd Kulesza
+tags:
+- survey
+- community
+summary: An analysis of the results from the 2019 Go Developer Survey.
+---
 
 ## What a response!
 
@@ -98,8 +101,8 @@
 which year-over-year changes may be the result of a shift in who responded to the survey,
 rather than changes in sentiment or behavior.
 
-.image survey2019/fig1.svg _ 700
-.image survey2019/fig2.svg _ 700
+{{image "survey2019/fig1.svg" 700}}
+{{image "survey2019/fig2.svg" 700}}
 
 Looking at Go experience, we see that a majority of respondents (56%) are
 relatively new to Go,
@@ -115,8 +118,8 @@
 of work and a different language while at work,
 but we see similar outliers across multiple survey questions.
 
-.image survey2019/fig3.svg _ 700
-.image survey2019/fig4.svg _ 700
+{{image "survey2019/fig3.svg" 700}}
+{{image "survey2019/fig4.svg" 700}}
 
 Respondents who have been using Go the longest have different backgrounds
 than newer Go developers.
@@ -128,7 +131,7 @@
 Python appears to be the language (other than Go) familiar to the most respondents,
 regardless of how long they’ve been working with Go.
 
-.image survey2019/fig5.svg _ 750
+{{image "survey2019/fig5.svg" 750}}
 
 Last year we asked about which industries respondents work in,
 finding that a majority reported working in software,
@@ -143,7 +146,7 @@
 was to reduce the use of the "Software" category as a catch-all for respondents
 writing Go software for an industry that wasn’t explicitly listed.
 
-.image survey2019/fig6.svg _ 700
+{{image "survey2019/fig6.svg" 700}}
 
 Go is a successful open-source project, but that doesn’t mean the developers
 working with it are also writing free or open-source software.
@@ -153,7 +156,7 @@
 As the Go community expands, we see the proportion of respondents who’ve
 never contributed to Go open-source projects slowly trending up.
 
-.image survey2019/fig7.svg _ 700
+{{image "survey2019/fig7.svg" 700}}
 
 ## Developer tools
 
@@ -165,8 +168,8 @@
 Linux is used by 66% and macOS by 53%—both much higher than the StackOverflow audience,
 which reported 25% and 30%, respectively.
 
-.image survey2019/fig8.svg _ 700
-.image survey2019/fig9.svg _ 700
+{{image "survey2019/fig8.svg" 700}}
+{{image "survey2019/fig9.svg" 700}}
 
 The trend in editor consolidation has continued this year.
 GoLand saw the sharpest increase in use this year,
@@ -178,7 +181,7 @@
 aren’t being used at all,
 but they’re not what respondents say they _prefer_ to use for writing Go code.
 
-.image survey2019/fig10.svg _ 700
+{{image "survey2019/fig10.svg" 700}}
 
 This year we added a question about internal Go documentation tooling,
 such as [gddo](https://github.com/golang/gddo).
@@ -191,7 +194,7 @@
 their server was a combination of low perceived benefits (23%) versus the
 amount of effort required to initially set it up and maintain it (38%).
 
-.image survey2019/fig11.svg _ 700
+{{image "survey2019/fig11.svg" 700}}
 
 ## Sentiments towards Go
 
@@ -208,14 +211,14 @@
 when we remove participants who never saw the question,
 we see it’s been fairly stable since 2016.
 
-.image survey2019/fig12.svg _ 700
+{{image "survey2019/fig12.svg" 700}}
 
 Looking at sentiments toward problem solving in the Go ecosystem,
 we see similar results.
 Large percentages of respondents agreed with each statement (82%–88%),
 and these rates have been largely stable over the past four years.
 
-.image survey2019/fig13.svg _ 700
+{{image "survey2019/fig13.svg" 700}}
 
 This year we took a more nuanced look at satisfaction across industries
 to establish a baseline.
@@ -231,8 +234,8 @@
 Each of these topics was rated "very" or "critically" important by a majority
 of respondents but had significantly lower satisfaction scores compared to other topics.
 
-.image survey2019/fig14.svg _ 800
-.image survey2019/fig15.svg _ 750
+{{image "survey2019/fig14.svg" 800}}
+{{image "survey2019/fig15.svg" 750}}
 
 Turning to sentiments toward the Go community,
 we see some differences from prior years.
@@ -257,7 +260,7 @@
 In other words, the longer a respondent has been using Go,
 the more likely they were to agree with each of these statements.
 
-.image survey2019/fig16.svg _ 700
+{{image "survey2019/fig16.svg" 700}}
 
 This likely comes as no surprise, but people who responded to the Go Developer
 Survey tended to like Go.
@@ -271,14 +274,14 @@
 In particular, Python is the language and ecosystem that Go developers are
 most likely to also enjoy building with.
 
-.image survey2019/fig17.svg _ 700
+{{image "survey2019/fig17.svg" 700}}
 
 In 2018 we first asked the "Would you recommend…" [Net Promoter Score](https://en.wikipedia.org/wiki/Net_Promoter) (NPS) question,
 yielding a score of 61.
 This year our NPS result is a statistically unchanged 60 (67% "promoters"
 minus 7% "detractors").
 
-.image survey2019/fig18.svg _ 700
+{{image "survey2019/fig18.svg" 700}}
 
 ## Working with Go
 
@@ -303,8 +306,8 @@
 network programming (42%), systems programming (38%),
 and DevOps tasks (37%).
 
-.image survey2019/fig19.svg _ 700
-.image survey2019/fig20.svg _ 700
+{{image "survey2019/fig19.svg" 700}}
+{{image "survey2019/fig20.svg" 700}}
 
 In addition to what respondents are building,
 we also asked about some of the development techniques they use.
@@ -315,14 +318,14 @@
 profiling, and testing with the race detector were not uncommon,
 with ~50% of respondents depending upon at least one of these techniques.
 
-.image survey2019/fig21.svg _ 700
+{{image "survey2019/fig21.svg" 700}}
 
 Regarding package management, we found that the vast majority of respondents
 have adopted modules for Go (89%).
 This has been a big shift for developers,
 and nearly the entire community appears to be going through it simultaneously.
 
-.image survey2019/fig22.svg _ 700
+{{image "survey2019/fig22.svg" 700}}
 
 We also found that 75% of respondents evaluate the current Go release for production use,
 with an additional 12% waiting one release cycle.
@@ -332,7 +335,7 @@
 support new stable releases of Go.
 
 
-.image survey2019/fig23.svg _ 700
+{{image "survey2019/fig23.svg" 700}}
 
 ## Go in the clouds
 
@@ -389,9 +392,9 @@
 SDK improvements were also the second most common request for both GCP (9%)
 and Azure (18%) developers.
 
-.image survey2019/fig24.svg _ 700
-.image survey2019/fig25.svg _ 700
-.image survey2019/fig26.svg _ 700
+{{image "survey2019/fig24.svg" 700}}
+{{image "survey2019/fig25.svg" 700}}
+{{image "survey2019/fig26.svg" 700}}
 
 ## Pain points
 
@@ -408,7 +411,7 @@
 but we don’t know whether that decrease dramatically accelerated this year,
 or was always a bit lower than our 2016–2018 numbers estimated.
 
-.image survey2019/fig27.svg _ 700
+{{image "survey2019/fig27.svg" 700}}
 
 The top two adoption blockers (working on an existing non-Go project and
 working on a team that prefers a different language) don’t have direct technical solutions,
@@ -433,7 +436,7 @@
 not the entire population of survey respondents.
 
 
-.image survey2019/fig28.svg _ 700
+{{image "survey2019/fig28.svg" 700}}
 
 Respondents who said Go "isn’t an appropriate language" for what they work
 on had a wide variety of reasons and use-cases.
@@ -448,7 +451,7 @@
 An additional top reason cited by respondents was a need for better performance (9%),
 particularly for real-time computing.
 
-.image survey2019/fig29.svg _ 700
+{{image "survey2019/fig29.svg" 700}}
 
 The biggest challenges respondents reported remain largely consistent with last year.
 Go’s lack of generics and modules/package management still top the list
@@ -462,7 +465,7 @@
 particularly around modules, tooling, and the getting started experience,
 in the coming months.
 
-.image survey2019/fig30.svg _ 700
+{{image "survey2019/fig30.svg" 700}}
 
 Diagnosing faults and performance issues can be challenging in any language.
 Respondents told us their top challenge for both of these was not something
@@ -477,8 +480,8 @@
 and challenges making the tooling work in various environments (e.g.,
 debugging in containers, or getting performance profiles from production systems).
 
-.image survey2019/fig31.svg _ 700
-.image survey2019/fig32.svg _ 700
+{{image "survey2019/fig31.svg" 700}}
+{{image "survey2019/fig32.svg" 700}}
 
 Finally, when we asked what would most improve Go support in respondents’
 editing environment,
@@ -494,7 +497,7 @@
 many of these gopls improvements have already landed,
 and this continues to be a high-priority area for the team.
 
-.image survey2019/fig33.svg _ 700
+{{image "survey2019/fig33.svg" 700}}
 
 ## The Go community
 
@@ -502,7 +505,7 @@
 The other top sources of answers were godoc.org (47%),
 directly reading source code (42%), and golang.org (33%).
 
-.image survey2019/fig34.svg _ 700
+{{image "survey2019/fig34.svg" 700}}
 
 The long tail on the previous chart highlights the large variety of different
 sources (nearly all of them community-driven) and modalities that respondents
@@ -513,7 +516,7 @@
 who do not attend any Go-related events.
 For 2019, that proportion nearly reached two thirds of respondents (62%).
 
-.image survey2019/fig35.svg _ 700
+{{image "survey2019/fig35.svg" 700}}
 
 Due to updated Google-wide privacy guidelines,
 we can no longer ask about which countries respondents live in.
@@ -526,7 +529,7 @@
 Thus, the non-English numbers should be interpreted as likely minimums rather
 than an approximation of Go’s global audience.
 
-.image survey2019/fig36.svg _ 700
+{{image "survey2019/fig36.svg" 700}}
 
 We found 12% of respondents identify with a traditionally underrepresented group (e.g.,
 ethnicity, gender identity, et al.) and 3% identify as female.
@@ -550,9 +553,9 @@
 4%) than those who do not identify with an underrepresented group,
 highlighting the importance of our continued outreach efforts.
 
-.image survey2019/fig37.svg _ 700
-.image survey2019/fig38.svg _ 700
-.image survey2019/fig39.svg _ 800
+{{image "survey2019/fig37.svg" 700}}
+{{image "survey2019/fig38.svg" 700}}
+{{image "survey2019/fig39.svg" 800}}
 
 ## Conclusion
 
diff --git a/blog/_content/survey2019.article b/go.dev/_content/blog/survey2019.md
similarity index 88%
rename from blog/_content/survey2019.article
rename to go.dev/_content/blog/survey2019.md
index 3fb330a..7de29ac 100644
--- a/blog/_content/survey2019.article
+++ b/go.dev/_content/blog/survey2019.md
@@ -1,10 +1,13 @@
-# Announcing the 2019 Go Developer Survey
-20 Nov 2019
-Tags: survey, community
-Summary: Please take the 2019 Go Developer Survey. We want to hear from you!
-
-Todd Kulesza
-tkulesza@google.com
+---
+title: Announcing the 2019 Go Developer Survey
+date: 2019-11-20
+by:
+- Todd Kulesza
+tags:
+- survey
+- community
+summary: Please take the 2019 Go Developer Survey. We want to hear from you!
+---
 
 ## Help shape the future of Go
 
diff --git a/blog/_content/survey2019/fig1.svg b/go.dev/_content/blog/survey2019/fig1.svg
similarity index 100%
rename from blog/_content/survey2019/fig1.svg
rename to go.dev/_content/blog/survey2019/fig1.svg
diff --git a/blog/_content/survey2019/fig10.svg b/go.dev/_content/blog/survey2019/fig10.svg
similarity index 100%
rename from blog/_content/survey2019/fig10.svg
rename to go.dev/_content/blog/survey2019/fig10.svg
diff --git a/blog/_content/survey2019/fig11.svg b/go.dev/_content/blog/survey2019/fig11.svg
similarity index 100%
rename from blog/_content/survey2019/fig11.svg
rename to go.dev/_content/blog/survey2019/fig11.svg
diff --git a/blog/_content/survey2019/fig12.svg b/go.dev/_content/blog/survey2019/fig12.svg
similarity index 100%
rename from blog/_content/survey2019/fig12.svg
rename to go.dev/_content/blog/survey2019/fig12.svg
diff --git a/blog/_content/survey2019/fig13.svg b/go.dev/_content/blog/survey2019/fig13.svg
similarity index 100%
rename from blog/_content/survey2019/fig13.svg
rename to go.dev/_content/blog/survey2019/fig13.svg
diff --git a/blog/_content/survey2019/fig14.svg b/go.dev/_content/blog/survey2019/fig14.svg
similarity index 100%
rename from blog/_content/survey2019/fig14.svg
rename to go.dev/_content/blog/survey2019/fig14.svg
diff --git a/blog/_content/survey2019/fig15.svg b/go.dev/_content/blog/survey2019/fig15.svg
similarity index 100%
rename from blog/_content/survey2019/fig15.svg
rename to go.dev/_content/blog/survey2019/fig15.svg
diff --git a/blog/_content/survey2019/fig16.svg b/go.dev/_content/blog/survey2019/fig16.svg
similarity index 100%
rename from blog/_content/survey2019/fig16.svg
rename to go.dev/_content/blog/survey2019/fig16.svg
diff --git a/blog/_content/survey2019/fig17.svg b/go.dev/_content/blog/survey2019/fig17.svg
similarity index 100%
rename from blog/_content/survey2019/fig17.svg
rename to go.dev/_content/blog/survey2019/fig17.svg
diff --git a/blog/_content/survey2019/fig18.svg b/go.dev/_content/blog/survey2019/fig18.svg
similarity index 100%
rename from blog/_content/survey2019/fig18.svg
rename to go.dev/_content/blog/survey2019/fig18.svg
diff --git a/blog/_content/survey2019/fig19.svg b/go.dev/_content/blog/survey2019/fig19.svg
similarity index 100%
rename from blog/_content/survey2019/fig19.svg
rename to go.dev/_content/blog/survey2019/fig19.svg
diff --git a/blog/_content/survey2019/fig2.svg b/go.dev/_content/blog/survey2019/fig2.svg
similarity index 100%
rename from blog/_content/survey2019/fig2.svg
rename to go.dev/_content/blog/survey2019/fig2.svg
diff --git a/blog/_content/survey2019/fig20.svg b/go.dev/_content/blog/survey2019/fig20.svg
similarity index 100%
rename from blog/_content/survey2019/fig20.svg
rename to go.dev/_content/blog/survey2019/fig20.svg
diff --git a/blog/_content/survey2019/fig21.svg b/go.dev/_content/blog/survey2019/fig21.svg
similarity index 100%
rename from blog/_content/survey2019/fig21.svg
rename to go.dev/_content/blog/survey2019/fig21.svg
diff --git a/blog/_content/survey2019/fig22.svg b/go.dev/_content/blog/survey2019/fig22.svg
similarity index 100%
rename from blog/_content/survey2019/fig22.svg
rename to go.dev/_content/blog/survey2019/fig22.svg
diff --git a/blog/_content/survey2019/fig23.svg b/go.dev/_content/blog/survey2019/fig23.svg
similarity index 100%
rename from blog/_content/survey2019/fig23.svg
rename to go.dev/_content/blog/survey2019/fig23.svg
diff --git a/blog/_content/survey2019/fig24.svg b/go.dev/_content/blog/survey2019/fig24.svg
similarity index 100%
rename from blog/_content/survey2019/fig24.svg
rename to go.dev/_content/blog/survey2019/fig24.svg
diff --git a/blog/_content/survey2019/fig25.svg b/go.dev/_content/blog/survey2019/fig25.svg
similarity index 100%
rename from blog/_content/survey2019/fig25.svg
rename to go.dev/_content/blog/survey2019/fig25.svg
diff --git a/blog/_content/survey2019/fig26.svg b/go.dev/_content/blog/survey2019/fig26.svg
similarity index 100%
rename from blog/_content/survey2019/fig26.svg
rename to go.dev/_content/blog/survey2019/fig26.svg
diff --git a/blog/_content/survey2019/fig27.svg b/go.dev/_content/blog/survey2019/fig27.svg
similarity index 100%
rename from blog/_content/survey2019/fig27.svg
rename to go.dev/_content/blog/survey2019/fig27.svg
diff --git a/blog/_content/survey2019/fig28.svg b/go.dev/_content/blog/survey2019/fig28.svg
similarity index 100%
rename from blog/_content/survey2019/fig28.svg
rename to go.dev/_content/blog/survey2019/fig28.svg
diff --git a/blog/_content/survey2019/fig29.svg b/go.dev/_content/blog/survey2019/fig29.svg
similarity index 100%
rename from blog/_content/survey2019/fig29.svg
rename to go.dev/_content/blog/survey2019/fig29.svg
diff --git a/blog/_content/survey2019/fig3.svg b/go.dev/_content/blog/survey2019/fig3.svg
similarity index 100%
rename from blog/_content/survey2019/fig3.svg
rename to go.dev/_content/blog/survey2019/fig3.svg
diff --git a/blog/_content/survey2019/fig30.svg b/go.dev/_content/blog/survey2019/fig30.svg
similarity index 100%
rename from blog/_content/survey2019/fig30.svg
rename to go.dev/_content/blog/survey2019/fig30.svg
diff --git a/blog/_content/survey2019/fig31.svg b/go.dev/_content/blog/survey2019/fig31.svg
similarity index 100%
rename from blog/_content/survey2019/fig31.svg
rename to go.dev/_content/blog/survey2019/fig31.svg
diff --git a/blog/_content/survey2019/fig32.svg b/go.dev/_content/blog/survey2019/fig32.svg
similarity index 100%
rename from blog/_content/survey2019/fig32.svg
rename to go.dev/_content/blog/survey2019/fig32.svg
diff --git a/blog/_content/survey2019/fig33.svg b/go.dev/_content/blog/survey2019/fig33.svg
similarity index 100%
rename from blog/_content/survey2019/fig33.svg
rename to go.dev/_content/blog/survey2019/fig33.svg
diff --git a/blog/_content/survey2019/fig34.svg b/go.dev/_content/blog/survey2019/fig34.svg
similarity index 100%
rename from blog/_content/survey2019/fig34.svg
rename to go.dev/_content/blog/survey2019/fig34.svg
diff --git a/blog/_content/survey2019/fig35.svg b/go.dev/_content/blog/survey2019/fig35.svg
similarity index 100%
rename from blog/_content/survey2019/fig35.svg
rename to go.dev/_content/blog/survey2019/fig35.svg
diff --git a/blog/_content/survey2019/fig36.svg b/go.dev/_content/blog/survey2019/fig36.svg
similarity index 100%
rename from blog/_content/survey2019/fig36.svg
rename to go.dev/_content/blog/survey2019/fig36.svg
diff --git a/blog/_content/survey2019/fig37.svg b/go.dev/_content/blog/survey2019/fig37.svg
similarity index 100%
rename from blog/_content/survey2019/fig37.svg
rename to go.dev/_content/blog/survey2019/fig37.svg
diff --git a/blog/_content/survey2019/fig38.svg b/go.dev/_content/blog/survey2019/fig38.svg
similarity index 100%
rename from blog/_content/survey2019/fig38.svg
rename to go.dev/_content/blog/survey2019/fig38.svg
diff --git a/blog/_content/survey2019/fig39.svg b/go.dev/_content/blog/survey2019/fig39.svg
similarity index 100%
rename from blog/_content/survey2019/fig39.svg
rename to go.dev/_content/blog/survey2019/fig39.svg
diff --git a/blog/_content/survey2019/fig4.svg b/go.dev/_content/blog/survey2019/fig4.svg
similarity index 100%
rename from blog/_content/survey2019/fig4.svg
rename to go.dev/_content/blog/survey2019/fig4.svg
diff --git a/blog/_content/survey2019/fig5.svg b/go.dev/_content/blog/survey2019/fig5.svg
similarity index 100%
rename from blog/_content/survey2019/fig5.svg
rename to go.dev/_content/blog/survey2019/fig5.svg
diff --git a/blog/_content/survey2019/fig6.svg b/go.dev/_content/blog/survey2019/fig6.svg
similarity index 100%
rename from blog/_content/survey2019/fig6.svg
rename to go.dev/_content/blog/survey2019/fig6.svg
diff --git a/blog/_content/survey2019/fig7.svg b/go.dev/_content/blog/survey2019/fig7.svg
similarity index 100%
rename from blog/_content/survey2019/fig7.svg
rename to go.dev/_content/blog/survey2019/fig7.svg
diff --git a/blog/_content/survey2019/fig8.svg b/go.dev/_content/blog/survey2019/fig8.svg
similarity index 100%
rename from blog/_content/survey2019/fig8.svg
rename to go.dev/_content/blog/survey2019/fig8.svg
diff --git a/blog/_content/survey2019/fig9.svg b/go.dev/_content/blog/survey2019/fig9.svg
similarity index 100%
rename from blog/_content/survey2019/fig9.svg
rename to go.dev/_content/blog/survey2019/fig9.svg
diff --git a/blog/_content/survey2020-results.article b/go.dev/_content/blog/survey2020-results.md
similarity index 98%
rename from blog/_content/survey2020-results.article
rename to go.dev/_content/blog/survey2020-results.md
index 617900d..5868cf2 100644
--- a/blog/_content/survey2020-results.article
+++ b/go.dev/_content/blog/survey2020-results.md
@@ -1,10 +1,13 @@
-# Go Developer Survey 2020 Results
-9 Mar 2021
-Tags: survey, community
-Summary: An analysis of the results from the 2020 Go Developer Survey.
-
-Alice Merrick
-amerrick@google.com
+---
+title: Go Developer Survey 2020 Results
+date: 2021-03-09
+by:
+- Alice Merrick
+tags:
+- survey
+- community
+summary: An analysis of the results from the 2020 Go Developer Survey.
+---
 
 ## Thank you for the amazing response! {#thanks}
 
diff --git a/blog/_content/survey2020.article b/go.dev/_content/blog/survey2020.md
similarity index 89%
rename from blog/_content/survey2020.article
rename to go.dev/_content/blog/survey2020.md
index 95bcb72..c192715 100644
--- a/blog/_content/survey2020.article
+++ b/go.dev/_content/blog/survey2020.md
@@ -1,10 +1,13 @@
-# Announcing the 2020 Go Developer Survey
-20 Oct 2020
-Tags: survey, community
-Summary: Please take the 2020 Go Developer Survey. We want to hear from you!
-
-Alice Merrick
-amerrick@google.com
+---
+title: Announcing the 2020 Go Developer Survey
+date: 2020-10-20
+by:
+- Alice Merrick
+tags:
+- survey
+- community
+summary: Please take the 2020 Go Developer Survey. We want to hear from you!
+---
 
 ## Help shape the future of Go {#help}
 
diff --git a/blog/_content/survey2020/app_context.svg b/go.dev/_content/blog/survey2020/app_context.svg
similarity index 100%
rename from blog/_content/survey2020/app_context.svg
rename to go.dev/_content/blog/survey2020/app_context.svg
diff --git a/blog/_content/survey2020/app_sat_bin.svg b/go.dev/_content/blog/survey2020/app_sat_bin.svg
similarity index 100%
rename from blog/_content/survey2020/app_sat_bin.svg
rename to go.dev/_content/blog/survey2020/app_sat_bin.svg
diff --git a/blog/_content/survey2020/app_yoy.svg b/go.dev/_content/blog/survey2020/app_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/app_yoy.svg
rename to go.dev/_content/blog/survey2020/app_yoy.svg
diff --git a/blog/_content/survey2020/at.svg b/go.dev/_content/blog/survey2020/at.svg
similarity index 100%
rename from blog/_content/survey2020/at.svg
rename to go.dev/_content/blog/survey2020/at.svg
diff --git a/blog/_content/survey2020/attitudes_community_yoy.svg b/go.dev/_content/blog/survey2020/attitudes_community_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/attitudes_community_yoy.svg
rename to go.dev/_content/blog/survey2020/attitudes_community_yoy.svg
diff --git a/blog/_content/survey2020/attitudes_yoy.svg b/go.dev/_content/blog/survey2020/attitudes_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/attitudes_yoy.svg
rename to go.dev/_content/blog/survey2020/attitudes_yoy.svg
diff --git a/blog/_content/survey2020/biggest.challenge.svg b/go.dev/_content/blog/survey2020/biggest.challenge.svg
similarity index 100%
rename from blog/_content/survey2020/biggest.challenge.svg
rename to go.dev/_content/blog/survey2020/biggest.challenge.svg
diff --git a/blog/_content/survey2020/biggest_challenge.svg b/go.dev/_content/blog/survey2020/biggest_challenge.svg
similarity index 100%
rename from blog/_content/survey2020/biggest_challenge.svg
rename to go.dev/_content/blog/survey2020/biggest_challenge.svg
diff --git a/blog/_content/survey2020/cli_platforms.svg b/go.dev/_content/blog/survey2020/cli_platforms.svg
similarity index 100%
rename from blog/_content/survey2020/cli_platforms.svg
rename to go.dev/_content/blog/survey2020/cli_platforms.svg
diff --git a/blog/_content/survey2020/cloud_csat.svg b/go.dev/_content/blog/survey2020/cloud_csat.svg
similarity index 100%
rename from blog/_content/survey2020/cloud_csat.svg
rename to go.dev/_content/blog/survey2020/cloud_csat.svg
diff --git a/blog/_content/survey2020/cloud_services_yoy.svg b/go.dev/_content/blog/survey2020/cloud_services_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/cloud_services_yoy.svg
rename to go.dev/_content/blog/survey2020/cloud_services_yoy.svg
diff --git a/blog/_content/survey2020/cloud_yoy.svg b/go.dev/_content/blog/survey2020/cloud_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/cloud_yoy.svg
rename to go.dev/_content/blog/survey2020/cloud_yoy.svg
diff --git a/blog/_content/survey2020/csat.svg b/go.dev/_content/blog/survey2020/csat.svg
similarity index 100%
rename from blog/_content/survey2020/csat.svg
rename to go.dev/_content/blog/survey2020/csat.svg
diff --git a/blog/_content/survey2020/devex_yoy.svg b/go.dev/_content/blog/survey2020/devex_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/devex_yoy.svg
rename to go.dev/_content/blog/survey2020/devex_yoy.svg
diff --git a/blog/_content/survey2020/doc_helpfulness.svg b/go.dev/_content/blog/survey2020/doc_helpfulness.svg
similarity index 100%
rename from blog/_content/survey2020/doc_helpfulness.svg
rename to go.dev/_content/blog/survey2020/doc_helpfulness.svg
diff --git a/blog/_content/survey2020/doc_struggles.svg b/go.dev/_content/blog/survey2020/doc_struggles.svg
similarity index 100%
rename from blog/_content/survey2020/doc_struggles.svg
rename to go.dev/_content/blog/survey2020/doc_struggles.svg
diff --git a/blog/_content/survey2020/domain_yoy.svg b/go.dev/_content/blog/survey2020/domain_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/domain_yoy.svg
rename to go.dev/_content/blog/survey2020/domain_yoy.svg
diff --git a/blog/_content/survey2020/dpe.svg b/go.dev/_content/blog/survey2020/dpe.svg
similarity index 100%
rename from blog/_content/survey2020/dpe.svg
rename to go.dev/_content/blog/survey2020/dpe.svg
diff --git a/blog/_content/survey2020/editor_improvements_means.svg b/go.dev/_content/blog/survey2020/editor_improvements_means.svg
similarity index 100%
rename from blog/_content/survey2020/editor_improvements_means.svg
rename to go.dev/_content/blog/survey2020/editor_improvements_means.svg
diff --git a/blog/_content/survey2020/editor_pref_yoy.svg b/go.dev/_content/blog/survey2020/editor_pref_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/editor_pref_yoy.svg
rename to go.dev/_content/blog/survey2020/editor_pref_yoy.svg
diff --git a/blog/_content/survey2020/events.svg b/go.dev/_content/blog/survey2020/events.svg
similarity index 100%
rename from blog/_content/survey2020/events.svg
rename to go.dev/_content/blog/survey2020/events.svg
diff --git a/blog/_content/survey2020/feature_sat_yoy.svg b/go.dev/_content/blog/survey2020/feature_sat_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/feature_sat_yoy.svg
rename to go.dev/_content/blog/survey2020/feature_sat_yoy.svg
diff --git a/blog/_content/survey2020/foss_yoy.svg b/go.dev/_content/blog/survey2020/foss_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/foss_yoy.svg
rename to go.dev/_content/blog/survey2020/foss_yoy.svg
diff --git a/blog/_content/survey2020/goblockers_yoy_sans_na.svg b/go.dev/_content/blog/survey2020/goblockers_yoy_sans_na.svg
similarity index 100%
rename from blog/_content/survey2020/goblockers_yoy_sans_na.svg
rename to go.dev/_content/blog/survey2020/goblockers_yoy_sans_na.svg
diff --git a/blog/_content/survey2020/goex_yoy.svg b/go.dev/_content/blog/survey2020/goex_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/goex_yoy.svg
rename to go.dev/_content/blog/survey2020/goex_yoy.svg
diff --git a/blog/_content/survey2020/gofreq_yoy.svg b/go.dev/_content/blog/survey2020/gofreq_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/gofreq_yoy.svg
rename to go.dev/_content/blog/survey2020/gofreq_yoy.svg
diff --git a/blog/_content/survey2020/industry_yoy.svg b/go.dev/_content/blog/survey2020/industry_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/industry_yoy.svg
rename to go.dev/_content/blog/survey2020/industry_yoy.svg
diff --git a/blog/_content/survey2020/job_responsibility.svg b/go.dev/_content/blog/survey2020/job_responsibility.svg
similarity index 100%
rename from blog/_content/survey2020/job_responsibility.svg
rename to go.dev/_content/blog/survey2020/job_responsibility.svg
diff --git a/blog/_content/survey2020/missing_features.svg b/go.dev/_content/blog/survey2020/missing_features.svg
similarity index 100%
rename from blog/_content/survey2020/missing_features.svg
rename to go.dev/_content/blog/survey2020/missing_features.svg
diff --git a/blog/_content/survey2020/modules_adoption_yoy.svg b/go.dev/_content/blog/survey2020/modules_adoption_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/modules_adoption_yoy.svg
rename to go.dev/_content/blog/survey2020/modules_adoption_yoy.svg
diff --git a/blog/_content/survey2020/modules_sat_yoy.svg b/go.dev/_content/blog/survey2020/modules_sat_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/modules_sat_yoy.svg
rename to go.dev/_content/blog/survey2020/modules_sat_yoy.svg
diff --git a/blog/_content/survey2020/more_welcoming.svg b/go.dev/_content/blog/survey2020/more_welcoming.svg
similarity index 100%
rename from blog/_content/survey2020/more_welcoming.svg
rename to go.dev/_content/blog/survey2020/more_welcoming.svg
diff --git a/blog/_content/survey2020/nps.svg b/go.dev/_content/blog/survey2020/nps.svg
similarity index 100%
rename from blog/_content/survey2020/nps.svg
rename to go.dev/_content/blog/survey2020/nps.svg
diff --git a/blog/_content/survey2020/orgsize.svg b/go.dev/_content/blog/survey2020/orgsize.svg
similarity index 100%
rename from blog/_content/survey2020/orgsize.svg
rename to go.dev/_content/blog/survey2020/orgsize.svg
diff --git a/blog/_content/survey2020/os_yoy.svg b/go.dev/_content/blog/survey2020/os_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/os_yoy.svg
rename to go.dev/_content/blog/survey2020/os_yoy.svg
diff --git a/blog/_content/survey2020/prod.svg b/go.dev/_content/blog/survey2020/prod.svg
similarity index 100%
rename from blog/_content/survey2020/prod.svg
rename to go.dev/_content/blog/survey2020/prod.svg
diff --git a/blog/_content/survey2020/prod_time.svg b/go.dev/_content/blog/survey2020/prod_time.svg
similarity index 100%
rename from blog/_content/survey2020/prod_time.svg
rename to go.dev/_content/blog/survey2020/prod_time.svg
diff --git a/blog/_content/survey2020/refactor_time.svg b/go.dev/_content/blog/survey2020/refactor_time.svg
similarity index 100%
rename from blog/_content/survey2020/refactor_time.svg
rename to go.dev/_content/blog/survey2020/refactor_time.svg
diff --git a/blog/_content/survey2020/resources.svg b/go.dev/_content/blog/survey2020/resources.svg
similarity index 100%
rename from blog/_content/survey2020/resources.svg
rename to go.dev/_content/blog/survey2020/resources.svg
diff --git a/blog/_content/survey2020/underrep.svg b/go.dev/_content/blog/survey2020/underrep.svg
similarity index 100%
rename from blog/_content/survey2020/underrep.svg
rename to go.dev/_content/blog/survey2020/underrep.svg
diff --git a/blog/_content/survey2020/underrep_groups_women.svg b/go.dev/_content/blog/survey2020/underrep_groups_women.svg
similarity index 100%
rename from blog/_content/survey2020/underrep_groups_women.svg
rename to go.dev/_content/blog/survey2020/underrep_groups_women.svg
diff --git a/blog/_content/survey2020/update_time.svg b/go.dev/_content/blog/survey2020/update_time.svg
similarity index 100%
rename from blog/_content/survey2020/update_time.svg
rename to go.dev/_content/blog/survey2020/update_time.svg
diff --git a/blog/_content/survey2020/welcome_underrep.svg b/go.dev/_content/blog/survey2020/welcome_underrep.svg
similarity index 100%
rename from blog/_content/survey2020/welcome_underrep.svg
rename to go.dev/_content/blog/survey2020/welcome_underrep.svg
diff --git a/blog/_content/survey2020/where_yoy.svg b/go.dev/_content/blog/survey2020/where_yoy.svg
similarity index 100%
rename from blog/_content/survey2020/where_yoy.svg
rename to go.dev/_content/blog/survey2020/where_yoy.svg
diff --git a/blog/_content/survey2020/why_printf.svg b/go.dev/_content/blog/survey2020/why_printf.svg
similarity index 100%
rename from blog/_content/survey2020/why_printf.svg
rename to go.dev/_content/blog/survey2020/why_printf.svg
diff --git a/blog/_content/sydney-gtug.article b/go.dev/_content/blog/sydney-gtug.md
similarity index 75%
rename from blog/_content/sydney-gtug.article
rename to go.dev/_content/blog/sydney-gtug.md
index 486c5e6..8715cdc 100644
--- a/blog/_content/sydney-gtug.article
+++ b/go.dev/_content/blog/sydney-gtug.md
@@ -1,12 +1,16 @@
-# Two Go Talks: "Lexical Scanning in Go" and "Cuddle: an App Engine Demo"
-1 Sep 2011
-Tags: appengine, lexer, talk, video
-Summary: Two talks about Go from the Sydney GTUG: Rob Pike explains lexical scanning, and Andrew Gerrand builds a simple real-time chat using App Engine. 
-OldURL: /two-go-talks-lexical-scanning-in-go-and
+---
+title: "Two Go Talks: \"Lexical Scanning in Go\" and \"Cuddle: an App Engine Demo\""
+date: 2011-09-01
+by:
+- Andrew Gerrand
+tags:
+- appengine
+- lexer
+- talk
+- video
+summary: "Two talks about Go from the Sydney GTUG: Rob Pike explains lexical scanning, and Andrew Gerrand builds a simple real-time chat using App Engine."
+---
 
-Andrew Gerrand
-
-##
 
 On Tuesday night Rob Pike and Andrew Gerrand each presented at the [Sydney Google Technology User Group](http://www.sydney-gtug.org/).
 
@@ -14,7 +18,7 @@
 discusses the design of  a particularly interesting and idiomatic piece of Go code,
 the lexer component of the new [template package.](https://golang.org/pkg/exp/template/)
 
-.iframe //www.youtube.com/embed/HxaD_trXwRE 345 560
+{{video "https://www.youtube.com/embed/HxaD_trXwRE"}}
 
 The slides are [available here](http://cuddle.googlecode.com/hg/talk/lex.html).
 The new template package is available as [exp/template](https://golang.org/pkg/exp/template/) in Go release r59.
@@ -28,7 +32,7 @@
 It also includes a question and answer session that covers [Go for App Engine](http://code.google.com/appengine/docs/go/gettingstarted/)
 and Go more generally.
 
-.iframe //www.youtube.com/embed/HQtLRqqB-Kk 345 560
+{{video "https://www.youtube.com/embed/HQtLRqqB-Kk"}}
 
 The slides are [available here](http://cuddle.googlecode.com/hg/talk/index.html).
 The code is available at the [cuddle Google Code project](http://code.google.com/p/cuddle/).
diff --git a/go.dev/_content/blog/the-app-engine-sdk-and-workspaces-gopath.md b/go.dev/_content/blog/the-app-engine-sdk-and-workspaces-gopath.md
new file mode 100644
index 0000000..aa3ec7d
--- /dev/null
+++ b/go.dev/_content/blog/the-app-engine-sdk-and-workspaces-gopath.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/appengine-gopath
+---
diff --git a/go.dev/_content/blog/the-path-to-go-1.md b/go.dev/_content/blog/the-path-to-go-1.md
new file mode 100644
index 0000000..432c09c
--- /dev/null
+++ b/go.dev/_content/blog/the-path-to-go-1.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/go1-path
+---
diff --git a/go.dev/_content/blog/the-vs-code-go-extension-joins-the-go-project.md b/go.dev/_content/blog/the-vs-code-go-extension-joins-the-go-project.md
new file mode 100644
index 0000000..8af0a29
--- /dev/null
+++ b/go.dev/_content/blog/the-vs-code-go-extension-joins-the-go-project.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/vscode-go
+---
diff --git a/go.dev/_content/blog/third-party-libraries-goprotobuf-and.md b/go.dev/_content/blog/third-party-libraries-goprotobuf-and.md
new file mode 100644
index 0000000..670f058
--- /dev/null
+++ b/go.dev/_content/blog/third-party-libraries-goprotobuf-and.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/protobuf
+---
diff --git a/blog/_content/tour.article b/go.dev/_content/blog/tour.md
similarity index 79%
rename from blog/_content/tour.article
rename to go.dev/_content/blog/tour.md
index a57725e..634cfbf 100644
--- a/blog/_content/tour.article
+++ b/go.dev/_content/blog/tour.md
@@ -1,12 +1,14 @@
-# Learn Go from your browser
-4 Oct 2011
-Tags: playground, tour
-Summary: Announcing the Go tour, https://tour.golang.org/.
-OldURL: /learn-go-from-your-browser
+---
+title: Learn Go from your browser
+date: 2011-10-04
+by:
+- Andrew Gerrand
+tags:
+- playground
+- tour
+summary: "Announcing the Go tour, https://tour.golang.org/."
+---
 
-Andrew Gerrand
-
-##
 
 We are excited to announce [A Tour of Go](https://tour.golang.org/),
 a guided tour of the Go programming language you can run from your browser.
diff --git a/blog/_content/toward-go2.article b/go.dev/_content/blog/toward-go2.md
similarity index 97%
rename from blog/_content/toward-go2.article
rename to go.dev/_content/blog/toward-go2.md
index ae7f6df..229bb9b 100644
--- a/blog/_content/toward-go2.article
+++ b/go.dev/_content/blog/toward-go2.md
@@ -1,9 +1,12 @@
-# Toward Go 2
-13 Jul 2017
-Tags: community
-Summary: How we will all work together toward Go 2.
-
-Russ Cox
+---
+title: Toward Go 2
+date: 2017-07-13
+by:
+- Russ Cox
+tags:
+- community
+summary: How we will all work together toward Go 2.
+---
 
 ## Introduction
 
@@ -17,7 +20,7 @@
 days, Rob suggested the name “Go.”
 
 <div style="margin-left: 2em;">
-.image toward-go2/mail.png _ 446
+{{image "toward-go2/mail.png" 446}}
 </div>
 
 The next year, Ian Lance Taylor and I joined the team, and together
@@ -25,7 +28,7 @@
 to the [open-source release](https://opensource.googleblog.com/2009/11/hey-ho-lets-go.html) on November 10, 2009.
 
 <div style="margin-left: 2em;">
-.image toward-go2/tweet.png _ 467
+{{image "toward-go2/tweet.png" 467}}
 </div>
 
 For the next two years, with the help of the new Go open source
@@ -33,14 +36,14 @@
 and leading to the [plan for Go 1](https://blog.golang.org/preview-of-go-version-1), proposed on October 5, 2011.
 
 <div style="margin-left: 2em;">
-.image toward-go2/go1-preview.png _ 560
+{{image "toward-go2/go1-preview.png" 560}}
 </div>
 
 With more help from the Go community, we revised and implemented that
 plan, eventually [releasing Go 1](https://blog.golang.org/go1) on March 28, 2012.
 
 <div style="margin-left: 2em;">
-.image toward-go2/go1-release.png _ 556
+{{image "toward-go2/go1-release.png" 556}}
 </div>
 
 The release of Go 1 marked the culmination of nearly five years of
@@ -171,7 +174,7 @@
 since the first prototype was running.
 
 <div style="margin-left: 2em;">
-.image toward-go2/process.png _ 410
+{{image "toward-go2/process.png" 410}}
 </div>
 
 Step 1 is to use Go, to accumulate experience with it.
@@ -211,7 +214,7 @@
 ## Explaining Problems
 
 <div style="margin-left: 2em;">
-.image toward-go2/process2.png _ 410
+{{image "toward-go2/process2.png" 410}}
 </div>
 
 There are two parts to explaining a problem. The first part—the easier
@@ -232,7 +235,7 @@
 renaming os.Error to error.Value while we were planning Go 1.
 
 <div style="margin-left: 2em;">
-.image toward-go2/error.png _ 495
+{{image "toward-go2/error.png" 495}}
 </div>
 
 It begins with a precise, one-line statement of the problem: in very
@@ -461,7 +464,7 @@
 ## Solutions
 
 <div style="margin-left: 2em;">
-.image toward-go2/process34.png _ 410
+{{image "toward-go2/process34.png" 410}}
 </div>
 
 Now that we know how we're going to identify and explain problems that
@@ -519,7 +522,7 @@
 ## Shipping Go 2
 
 <div style="margin-left: 2em;">
-.image toward-go2/process5.png _ 410
+{{image "toward-go2/process5.png" 410}}
 </div>
 
 Finally, how will we ship and deliver Go 2?
diff --git a/blog/_content/toward-go2/error.png b/go.dev/_content/blog/toward-go2/error.png
similarity index 100%
rename from blog/_content/toward-go2/error.png
rename to go.dev/_content/blog/toward-go2/error.png
Binary files differ
diff --git a/blog/_content/toward-go2/go1-preview.png b/go.dev/_content/blog/toward-go2/go1-preview.png
similarity index 100%
rename from blog/_content/toward-go2/go1-preview.png
rename to go.dev/_content/blog/toward-go2/go1-preview.png
Binary files differ
diff --git a/blog/_content/toward-go2/go1-release.png b/go.dev/_content/blog/toward-go2/go1-release.png
similarity index 100%
rename from blog/_content/toward-go2/go1-release.png
rename to go.dev/_content/blog/toward-go2/go1-release.png
Binary files differ
diff --git a/blog/_content/toward-go2/mail.png b/go.dev/_content/blog/toward-go2/mail.png
similarity index 100%
rename from blog/_content/toward-go2/mail.png
rename to go.dev/_content/blog/toward-go2/mail.png
Binary files differ
diff --git a/blog/_content/toward-go2/process.graffle b/go.dev/_content/blog/toward-go2/process.graffle
similarity index 100%
rename from blog/_content/toward-go2/process.graffle
rename to go.dev/_content/blog/toward-go2/process.graffle
Binary files differ
diff --git a/blog/_content/toward-go2/process.png b/go.dev/_content/blog/toward-go2/process.png
similarity index 100%
rename from blog/_content/toward-go2/process.png
rename to go.dev/_content/blog/toward-go2/process.png
Binary files differ
diff --git a/blog/_content/toward-go2/process.svg b/go.dev/_content/blog/toward-go2/process.svg
similarity index 100%
rename from blog/_content/toward-go2/process.svg
rename to go.dev/_content/blog/toward-go2/process.svg
diff --git a/blog/_content/toward-go2/process2.graffle b/go.dev/_content/blog/toward-go2/process2.graffle
similarity index 100%
rename from blog/_content/toward-go2/process2.graffle
rename to go.dev/_content/blog/toward-go2/process2.graffle
Binary files differ
diff --git a/blog/_content/toward-go2/process2.png b/go.dev/_content/blog/toward-go2/process2.png
similarity index 100%
rename from blog/_content/toward-go2/process2.png
rename to go.dev/_content/blog/toward-go2/process2.png
Binary files differ
diff --git a/blog/_content/toward-go2/process2.svg b/go.dev/_content/blog/toward-go2/process2.svg
similarity index 100%
rename from blog/_content/toward-go2/process2.svg
rename to go.dev/_content/blog/toward-go2/process2.svg
diff --git a/blog/_content/toward-go2/process34.graffle b/go.dev/_content/blog/toward-go2/process34.graffle
similarity index 100%
rename from blog/_content/toward-go2/process34.graffle
rename to go.dev/_content/blog/toward-go2/process34.graffle
Binary files differ
diff --git a/blog/_content/toward-go2/process34.png b/go.dev/_content/blog/toward-go2/process34.png
similarity index 100%
rename from blog/_content/toward-go2/process34.png
rename to go.dev/_content/blog/toward-go2/process34.png
Binary files differ
diff --git a/blog/_content/toward-go2/process34.svg b/go.dev/_content/blog/toward-go2/process34.svg
similarity index 100%
rename from blog/_content/toward-go2/process34.svg
rename to go.dev/_content/blog/toward-go2/process34.svg
diff --git a/blog/_content/toward-go2/process5.graffle b/go.dev/_content/blog/toward-go2/process5.graffle
similarity index 100%
rename from blog/_content/toward-go2/process5.graffle
rename to go.dev/_content/blog/toward-go2/process5.graffle
Binary files differ
diff --git a/blog/_content/toward-go2/process5.png b/go.dev/_content/blog/toward-go2/process5.png
similarity index 100%
rename from blog/_content/toward-go2/process5.png
rename to go.dev/_content/blog/toward-go2/process5.png
Binary files differ
diff --git a/blog/_content/toward-go2/process5.svg b/go.dev/_content/blog/toward-go2/process5.svg
similarity index 100%
rename from blog/_content/toward-go2/process5.svg
rename to go.dev/_content/blog/toward-go2/process5.svg
diff --git a/blog/_content/toward-go2/tweet.png b/go.dev/_content/blog/toward-go2/tweet.png
similarity index 100%
rename from blog/_content/toward-go2/tweet.png
rename to go.dev/_content/blog/toward-go2/tweet.png
Binary files differ
diff --git a/blog/_content/turkey-doodle.article b/go.dev/_content/blog/turkey-doodle.md
similarity index 78%
rename from blog/_content/turkey-doodle.article
rename to go.dev/_content/blog/turkey-doodle.md
index 8649279..1882090 100644
--- a/blog/_content/turkey-doodle.article
+++ b/go.dev/_content/blog/turkey-doodle.md
@@ -1,10 +1,14 @@
-# From zero to Go: launching on the Google homepage in 24 hours
-13 Dec 2011
-Tags: appengine, google, guest
-Summary: How Go helped launch the Google Doodle for Thanksgiving 2011.
-OldURL: /from-zero-to-go-launching-on-google
-
-Reinaldo Aguiar
+---
+title: "From zero to Go: launching on the Google homepage in 24 hours"
+date: 2011-12-13
+by:
+- Reinaldo Aguiar
+tags:
+- appengine
+- google
+- guest
+summary: How Go helped launch the Google Doodle for Thanksgiving 2011.
+---
 
 ## Introduction
 
@@ -19,7 +23,7 @@
 This interactivity is implemented in the browser by a combination of JavaScript,
 CSS and of course HTML, creating turkeys on the fly.
 
-.image turkey-doodle/image00.png
+{{image "turkey-doodle/image00.png"}}
 
 Once the user has created a personalized turkey it can be shared with friends
 and family by posting to Google+.
@@ -63,7 +67,7 @@
 
 The base for every doodle is the background:
 
-.image turkey-doodle/image01.jpg
+{{image "turkey-doodle/image01.jpg"}}
 
 A valid request URL might look like this:
 `http://google-turkey.appspot.com/thumb/20332620][http://google-turkey.appspot.com/thumb/20332620`
@@ -72,7 +76,7 @@
 which choice to draw for each layout element,
 as illustrated by this image:
 
-.image turkey-doodle/image03.png
+{{image "turkey-doodle/image03.png"}}
 
 The program's request handler parses the URL to determine which element
 is selected for each component,
@@ -174,66 +178,70 @@
 
 Here's the code for the request handler with explanatory comments:
 
-	func handler(w http.ResponseWriter, r *http.Request) {
-	    // [[https://blog.golang.org/2010/08/defer-panic-and-recover.html][Defer]] a function to recover from any panics.
-	    // When recovering from a panic, log the error condition to
-	    // the App Engine dashboard and send the default image to the user.
-	    defer func() {
-	        if err := recover(); err != nil {
-	            c := appengine.NewContext(r)
-	            c.Errorf("%s", err)
-	            c.Errorf("%s", "Traceback: %s", r.RawURL)
-	            if defaultImage != nil {
-	                w.Header().Set("Content-type", "image/jpeg")
-	                jpeg.Encode(w, defaultImage, &imageQuality)
-	            }
-	        }
-	    }()
+{{raw `
+<pre>
+func handler(w http.ResponseWriter, r *http.Request) {
+    // <a href="https://blog.golang.org/2010/08/defer-panic-and-recover.html">Defer</a> a function to recover from any panics.
+    // When recovering from a panic, log the error condition to
+    // the App Engine dashboard and send the default image to the user.
+    defer func() {
+        if err := recover(); err != nil {
+            c := appengine.NewContext(r)
+            c.Errorf("%s", err)
+            c.Errorf("%s", "Traceback: %s", r.RawURL)
+            if defaultImage != nil {
+                w.Header().Set("Content-type", "image/jpeg")
+                jpeg.Encode(w, defaultImage, &imageQuality)
+            }
+        }
+    }()
 
-	    // Load images from disk on the first request.
-	    loadOnce.Do(load)
+    // Load images from disk on the first request.
+    loadOnce.Do(load)
 
-	    // Make a copy of the background to draw into.
-	    bgRect := backgroundImage.Bounds()
-	    m := image.NewRGBA(bgRect.Dx(), bgRect.Dy())
-	    draw.Draw(m, m.Bounds(), backgroundImage, image.ZP, draw.Over)
+    // Make a copy of the background to draw into.
+    bgRect := backgroundImage.Bounds()
+    m := image.NewRGBA(bgRect.Dx(), bgRect.Dy())
+    draw.Draw(m, m.Bounds(), backgroundImage, image.ZP, draw.Over)
 
-	    // Process each character of the request string.
-	    code := strings.ToLower(r.URL.Path[len(prefix):])
-	    for i, p := range code {
-	        // Decode hex character p in place.
-	        if p < 'a' {
-	            // it's a digit
-	            p = p - '0'
-	        } else {
-	            // it's a letter
-	            p = p - 'a' + 10
-	        }
+    // Process each character of the request string.
+    code := strings.ToLower(r.URL.Path[len(prefix):])
+    for i, p := range code {
+        // Decode hex character p in place.
+        if p &lt; 'a' {
+            // it's a digit
+            p = p - '0'
+        } else {
+            // it's a letter
+            p = p - 'a' + 10
+        }
 
-	        t := urlMap[i]    // element type by index
-	        em := elements[t] // element images by type
-	        if p >= len(em) {
-	            panic(fmt.Sprintf("element index out of range %s: "+
-	                "%d >= %d", t, p, len(em)))
-	        }
+        t := urlMap[i]    // element type by index
+        em := elements[t] // element images by type
+        if p >= len(em) {
+            panic(fmt.Sprintf("element index out of range %s: "+
+                "%d >= %d", t, p, len(em)))
+        }
 
-	        // Draw the element to m,
-	        // using the layoutMap to specify its position.
-	        draw.Draw(m, layoutMap[t], em[p], image.ZP, draw.Over)
-	    }
+        // Draw the element to m,
+        // using the layoutMap to specify its position.
+        draw.Draw(m, layoutMap[t], em[p], image.ZP, draw.Over)
+    }
 
-	    // Encode JPEG image and write it as the response.
-	    w.Header().Set("Content-type", "image/jpeg")
-	    w.Header().Set("Cache-control", "public, max-age=259200")
-	    jpeg.Encode(w, m, &imageQuality)
-	}
+    // Encode JPEG image and write it as the response.
+    w.Header().Set("Content-type", "image/jpeg")
+    w.Header().Set("Cache-control", "public, max-age=259200")
+    jpeg.Encode(w, m, &imageQuality)
+}
+</pre>
+`}}
 
 For brevity, I've omitted several helper functions from these code listings.
 See the [source code](http://code.google.com/p/go-thanksgiving/source/browse/) for the full scoop.
 
 ## Performance
 
-.image turkey-doodle/image02.png
+{{image "turkey-doodle/image02.png"}}
 
 This chart - taken directly from the App Engine dashboard - shows average
 request latency during launch.
diff --git a/blog/_content/turkey-doodle/image00.png b/go.dev/_content/blog/turkey-doodle/image00.png
similarity index 100%
rename from blog/_content/turkey-doodle/image00.png
rename to go.dev/_content/blog/turkey-doodle/image00.png
Binary files differ
diff --git a/blog/_content/turkey-doodle/image01.jpg b/go.dev/_content/blog/turkey-doodle/image01.jpg
similarity index 100%
rename from blog/_content/turkey-doodle/image01.jpg
rename to go.dev/_content/blog/turkey-doodle/image01.jpg
Binary files differ
diff --git a/blog/_content/turkey-doodle/image02.png b/go.dev/_content/blog/turkey-doodle/image02.png
similarity index 100%
rename from blog/_content/turkey-doodle/image02.png
rename to go.dev/_content/blog/turkey-doodle/image02.png
Binary files differ
diff --git a/blog/_content/turkey-doodle/image03.png b/go.dev/_content/blog/turkey-doodle/image03.png
similarity index 100%
rename from blog/_content/turkey-doodle/image03.png
rename to go.dev/_content/blog/turkey-doodle/image03.png
Binary files differ
diff --git a/go.dev/_content/blog/two-go-talks-lexical-scanning-in-go-and.md b/go.dev/_content/blog/two-go-talks-lexical-scanning-in-go-and.md
new file mode 100644
index 0000000..6863830
--- /dev/null
+++ b/go.dev/_content/blog/two-go-talks-lexical-scanning-in-go-and.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/sydney-gtug
+---
diff --git a/blog/_content/two-recent-go-articles.article b/go.dev/_content/blog/two-recent-go-articles.md
similarity index 91%
rename from blog/_content/two-recent-go-articles.article
rename to go.dev/_content/blog/two-recent-go-articles.md
index 1fa92d4..f05d4d4 100644
--- a/blog/_content/two-recent-go-articles.article
+++ b/go.dev/_content/blog/two-recent-go-articles.md
@@ -1,9 +1,14 @@
-# Two recent Go articles
-6 Mar 2013
-Tags: google, talk, ethos
-Summary: Two Go articles: “Go at Google: Language Design in the Service of Software Engineering” and “Getting Started with Go, App Engine and Google+ API”
-
-Andrew Gerrand
+---
+title: Two recent Go articles
+date: 2013-03-06
+by:
+- Andrew Gerrand
+tags:
+- google
+- talk
+- ethos
+summary: "Two Go articles: “Go at Google: Language Design in the Service of Software Engineering” and “Getting Started with Go, App Engine and Google+ API”"
+---
 
 ## Introduction
 
diff --git a/blog/_content/two-recent-go-talks.article b/go.dev/_content/blog/two-recent-go-talks.md
similarity index 82%
rename from blog/_content/two-recent-go-talks.article
rename to go.dev/_content/blog/two-recent-go-talks.md
index ca4e44f..0e0000d 100644
--- a/blog/_content/two-recent-go-talks.article
+++ b/go.dev/_content/blog/two-recent-go-talks.md
@@ -1,9 +1,14 @@
-# Two recent Go talks
-2 Jan 2013
-Tags: talk, video, ethos
-Summary: Two Go talks: “Go: A Simple Programming Environment” and “Go: Code That Grows With Grace”.
-
-Andrew Gerrand
+---
+title: Two recent Go talks
+date: 2013-01-02
+by:
+- Andrew Gerrand
+tags:
+- talk
+- video
+- ethos
+summary: "Two Go talks: “Go: A Simple Programming Environment” and “Go: Code That Grows With Grace”."
+---
 
 ## Introduction
 
@@ -26,7 +31,7 @@
 that demonstrate the power,
 scope, and simplicity of the Go programming environment.
 
-.iframe //player.vimeo.com/video/53221558?badge=0 281 500
+{{video "https://player.vimeo.com/video/53221558?badge=0" 500 281}}
 
 See the [slide deck](https://talks.golang.org/2012/simple.slide) (use the left and right arrows to navigate).
 
@@ -41,6 +46,6 @@
 While the function of the program changes dramatically,
 Go's flexibility preserves the original design as it grows.
 
-.iframe //player.vimeo.com/video/53221560?badge=0 281 500
+{{video "https://player.vimeo.com/video/53221560?badge=0" 500 281}}
 
 See the [slide deck](https://talks.golang.org/2012/chat.slide) (use the left and right arrows to navigate).
diff --git a/go.dev/_content/blog/upcoming-google-io-go-events.md b/go.dev/_content/blog/upcoming-google-io-go-events.md
new file mode 100644
index 0000000..f117d07
--- /dev/null
+++ b/go.dev/_content/blog/upcoming-google-io-go-events.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/io2010-preview
+---
diff --git a/blog/_content/using-go-modules.article b/go.dev/_content/blog/using-go-modules.md
similarity index 97%
rename from blog/_content/using-go-modules.article
rename to go.dev/_content/blog/using-go-modules.md
index 0de509f..e07a2c0 100644
--- a/blog/_content/using-go-modules.article
+++ b/go.dev/_content/blog/using-go-modules.md
@@ -1,11 +1,14 @@
-# Using Go Modules
-19 Mar 2019
-Tags: tools, versioning
-Summary: An introduction to the basic operations needed to get started with Go modules.
-
-Tyler Bui-Palsulich
-
-Eno Compton
+---
+title: Using Go Modules
+date: 2019-03-19
+by:
+- Tyler Bui-Palsulich
+- Eno Compton
+tags:
+- tools
+- versioning
+summary: An introduction to the basic operations needed to get started with Go modules.
+---
 
 ## Introduction
 
diff --git a/blog/_content/v2-go-modules.article b/go.dev/_content/blog/v2-go-modules.md
similarity index 96%
rename from blog/_content/v2-go-modules.article
rename to go.dev/_content/blog/v2-go-modules.md
index f957d6d..c8e040f 100644
--- a/blog/_content/v2-go-modules.article
+++ b/go.dev/_content/blog/v2-go-modules.md
@@ -1,11 +1,14 @@
-# Go Modules: v2 and Beyond
-7 Nov 2019
-Tags: tools, versioning
-Summary: How to release major version 2 of your module.
-
-Jean de Klerk
-
-Tyler Bui-Palsulich
+---
+title: "Go Modules: v2 and Beyond"
+date: 2019-11-07
+by:
+- Jean de Klerk
+- Tyler Bui-Palsulich
+tags:
+- tools
+- versioning
+summary: How to release major version 2 of your module.
+---
 
 ## Introduction
 
diff --git a/blog/_content/versioning-proposal.article b/go.dev/_content/blog/versioning-proposal.md
similarity index 97%
rename from blog/_content/versioning-proposal.article
rename to go.dev/_content/blog/versioning-proposal.md
index a3907d9..fe3b8ba 100644
--- a/blog/_content/versioning-proposal.article
+++ b/go.dev/_content/blog/versioning-proposal.md
@@ -1,9 +1,13 @@
-# A Proposal for Package Versioning in Go
-26 Mar 2018
-Tags: tools, versioning
-Summary: Proposing official support for package versioning in Go, using Go modules.
-
-Russ Cox
+---
+title: A Proposal for Package Versioning in Go
+date: 2018-03-26
+by:
+- Russ Cox
+tags:
+- tools
+- versioning
+summary: Proposing official support for package versioning in Go, using Go modules.
+---
 
 ## Introduction
 
diff --git a/blog/_content/vscode-go.article b/go.dev/_content/blog/vscode-go.md
similarity index 94%
rename from blog/_content/vscode-go.article
rename to go.dev/_content/blog/vscode-go.md
index 0c325b4..53cd8ba 100644
--- a/blog/_content/vscode-go.article
+++ b/go.dev/_content/blog/vscode-go.md
@@ -1,11 +1,11 @@
-# The VS Code Go extension joins the Go project
-09 Jun 2020
-Summary: Announcement of VS Code Go’s move to the Go project.
-OldURL: /the-vs-code-go-extension-joins-the-go-project
+---
+title: The VS Code Go extension joins the Go project
+date: 2020-06-09
+by:
+- The Go team
+summary: Announcement of VS Code Go’s move to the Go project.
+---
 
-The Go team
-
-##
 
 When the Go project began, “an overarching goal was that Go do more to help the
 working programmer by enabling tooling, automating mundane tasks such as code
diff --git a/blog/_content/waza-talk.article b/go.dev/_content/blog/waza-talk.md
similarity index 80%
rename from blog/_content/waza-talk.article
rename to go.dev/_content/blog/waza-talk.md
index 5bf1895..9eb2592 100644
--- a/blog/_content/waza-talk.article
+++ b/go.dev/_content/blog/waza-talk.md
@@ -1,12 +1,15 @@
-# Concurrency is not parallelism
-16 Jan 2013
-Tags: concurrency, talk, video
-Summary: Watch Rob Pike's talk, _Concurrency is not parallelism._
-OldURL: /concurrency-is-not-parallelism
+---
+title: Concurrency is not parallelism
+date: 2013-01-16
+by:
+- Andrew Gerrand
+tags:
+- concurrency
+- talk
+- video
+summary: Watch Rob Pike's talk, _Concurrency is not parallelism._
+---
 
-Andrew Gerrand
-
-##
 
 If there's one thing most people know about Go,
 is that it is designed for concurrency.
@@ -23,7 +26,7 @@
 [Waza](http://waza.heroku.com/) conference entitled _Concurrency is not parallelism_,
 and a video recording of the talk was released a few months ago.
 
-.iframe //player.vimeo.com/video/49718712?badge=0 281 500
+{{video "https://player.vimeo.com/video/49718712?badge=0" 500 281}}
 
 The slides are available at [talks.golang.org](https://talks.golang.org/2012/waza.slide)
 (use the left and right arrow keys to navigate).
diff --git a/blog/_content/why-generics.article b/go.dev/_content/blog/why-generics.md
similarity index 97%
rename from blog/_content/why-generics.article
rename to go.dev/_content/blog/why-generics.md
index cb1553a..d1a0c91 100644
--- a/blog/_content/why-generics.article
+++ b/go.dev/_content/blog/why-generics.md
@@ -1,15 +1,20 @@
-# Why Generics?
-31 Jul 2019
-Tags: go2, proposals, generics
-Summary: Why should we add generics to Go, and what might they look like?
-
-Ian Lance Taylor
+---
+title: Why Generics?
+date: 2019-07-31
+by:
+- Ian Lance Taylor
+tags:
+- go2
+- proposals
+- generics
+summary: Why should we add generics to Go, and what might they look like?
+---
 
 ## Introduction
 
 This is the blog post version of my talk last week at Gophercon 2019.
 
-.iframe //www.youtube.com/embed/WzgLqE-3IhY?rel=0 309 549
+{{video "https://www.youtube.com/embed/WzgLqE-3IhY?rel=0"}}
 
 This article is about what it would mean to add generics to Go, and
 why I think we should do it.
@@ -43,6 +48,7 @@
 
 Let's say it's a slice of int.
 
+{{raw `
 	func ReverseInts(s []int) {
 		first := 0
 		last := len(s)
@@ -52,12 +58,14 @@
 			last--
 		}
 	}
+`}}
 
 Pretty simple, but even for a simple function like that you'd want to
 write a few test cases.
 In fact, when I did, I found a bug.
 I'm sure many readers have spotted it already.
 
+{{raw `
 	func ReverseInts(s []int) {
 		first := 0
 		last := len(s) - 1
@@ -67,11 +75,13 @@
 			last--
 		}
 	}
+`}}
 
 We need to subtract 1 when we set the variable last.
 
 Now let's reverse a slice of string.
 
+{{raw `
 	func ReverseStrings(s []string) {
 		first := 0
 		last := len(s) - 1
@@ -81,6 +91,7 @@
 			last--
 		}
 	}
+`}}
 
 If you compare `ReverseInts` and `ReverseStrings`, you'll see that the
 two functions are exactly the same, except for the type of the parameter.
@@ -353,6 +364,7 @@
 
 Here is the generic Reverse function in this design.
 
+{{raw `
 	func Reverse (type Element) (s []Element) {
 		first := 0
 		last := len(s) - 1
@@ -362,6 +374,7 @@
 			last--
 		}
 	}
+`}}
 
 You'll notice that the body of the function is exactly the same.
 Only the signature has changed.
@@ -415,6 +428,7 @@
 
 Let's take a quick look at a different function.
 
+{{raw `
 	func IndexByte (type T Sequence) (s T, b byte) int {
 		for i := 0; i < len(s); i++ {
 			if s[i] == b {
@@ -423,6 +437,7 @@
 		}
 		return -1
 	}
+`}}
 
 Currently both the bytes package and the strings package in the
 standard library have an `IndexByte` function.
@@ -553,12 +568,14 @@
 implementation should let us add it to the standard library.
 This is what it looks like with our design.
 
+{{raw `
 	func Min (type T Ordered) (a, b T) T {
 		if a < b {
 			return a
 		}
 		return b
 	}
+`}}
 
 The `Ordered` contract says that the type T has to be an ordered type,
 which means that it supports operators like less than, greater than,
@@ -595,12 +612,14 @@
 standard library somewhere) will look like this.  Here we're just
 referring to the contract Ordered defined in the package contracts.
 
+{{raw `
 	func Min (type T contracts.Ordered) (a, b T) T {
 		if a < b {
 			return a
 		}
 		return b
 	}
+`}}
 
 ### Generic data structures
 
@@ -628,6 +647,7 @@
 An unexported method returns a pointer either to the slot holding v,
 or to the location in the tree where it should go.
 
+{{raw `
 	func (t *Tree(E)) find(v E) **node(E) {
 		pn := &t.root
 		for *pn != nil {
@@ -642,6 +662,7 @@
 		}
 		return pn
 	}
+`}}
 
 The details here don't really matter, especially since I haven't
 tested this code.
diff --git a/blog/_content/wire.article b/go.dev/_content/blog/wire.md
similarity index 97%
rename from blog/_content/wire.article
rename to go.dev/_content/blog/wire.md
index 1f83ef2..a93dc3a 100644
--- a/blog/_content/wire.article
+++ b/go.dev/_content/blog/wire.md
@@ -1,8 +1,10 @@
-# Compile-time Dependency Injection With Go Cloud's Wire
-9 Oct 2018
-Summary: How to use Wire, a dependency injection tool for Go.
-
-Robert van Gent
+---
+title: Compile-time Dependency Injection With Go Cloud's Wire
+date: 2018-10-09
+by:
+- Robert van Gent
+summary: How to use Wire, a dependency injection tool for Go.
+---
 
 ## Overview
 
diff --git a/blog/_content/wrap.go b/go.dev/_content/blog/wrap.go
similarity index 100%
rename from blog/_content/wrap.go
rename to go.dev/_content/blog/wrap.go
diff --git a/go.dev/_content/blog/writing-scalable-app-engine.md b/go.dev/_content/blog/writing-scalable-app-engine.md
new file mode 100644
index 0000000..88dff9b
--- /dev/null
+++ b/go.dev/_content/blog/writing-scalable-app-engine.md
@@ -0,0 +1,3 @@
+---
+redirect: /blog/appengine-scalable
+---
diff --git a/go.dev/_content/blogfeed.tmpl b/go.dev/_content/blogfeed.tmpl
new file mode 100644
index 0000000..96eff4a
--- /dev/null
+++ b/go.dev/_content/blogfeed.tmpl
@@ -0,0 +1 @@
+{{block "layout" .}}{{.Content}}{{end}}
diff --git a/go.dev/_content/css/fonts.css b/go.dev/_content/css/fonts.css
new file mode 100644
index 0000000..ca35a71
--- /dev/null
+++ b/go.dev/_content/css/fonts.css
@@ -0,0 +1,69 @@
+@font-face {
+	font-family: 'Go';
+	src: url('/fonts/GoMedium-Italic.woff') format('woff');
+	font-weight: 500;
+	font-style: italic;
+}
+
+@font-face {
+	font-family: 'Go';
+	src: url('/fonts/Go-Italic.woff') format('woff');
+	font-weight: normal;
+	font-style: italic;
+}
+
+@font-face {
+	font-family: 'Go';
+	src: url('/fonts/Go-Bold.woff') format('woff');
+	font-weight: bold;
+	font-style: normal;
+}
+
+@font-face {
+	font-family: 'Go';
+	src: url('/fonts/GoMedium.woff') format('woff');
+	font-weight: 500;
+	font-style: normal;
+}
+
+@font-face {
+	font-family: 'Go';
+	src: url('/fonts/Go-BoldItalic.woff') format('woff');
+	font-weight: bold;
+	font-style: italic;
+}
+
+@font-face {
+	font-family: 'Go';
+	src: url('/fonts/GoRegular.woff') format('woff');
+	font-weight: normal;
+	font-style: normal;
+}
+
+@font-face {
+	font-family: 'Go Mono';
+	src: url('/fonts/GoMono-Bold.woff') format('woff');
+	font-weight: bold;
+	font-style: normal;
+}
+
+@font-face {
+	font-family: 'Go Mono';
+	src: url('/fonts/GoMono.woff') format('woff');
+	font-weight: normal;
+	font-style: normal;
+}
+
+@font-face {
+	font-family: 'Go Mono';
+	src: url('/fonts/GoMono-Italic.woff') format('woff');
+	font-weight: normal;
+	font-style: italic;
+}
+
+@font-face {
+	font-family: 'Go Mono';
+	src: url('/fonts/GoMono-BoldItalic.woff') format('woff');
+	font-weight: bold;
+	font-style: italic;
+}
diff --git a/go.dev/_content/css/styles.css b/go.dev/_content/css/styles.css
index ab6525d..a1f257c 100644
--- a/go.dev/_content/css/styles.css
+++ b/go.dev/_content/css/styles.css
@@ -3483,3 +3483,152 @@
     margin: 1rem 0 0;
   }
 }
+
+#blog h1.small {
+  font-weight: bold;
+  font-size: 1rem;
+}
+#blog a.head {
+  color: black;
+  text-decoration: none !important;
+}
+#blog a.head:hover {
+  text-decoration: underline;
+}
+#blog #content .author {
+  font-style: italic;
+}
+#blog #content .Article {
+  margin-bottom: 50px;
+}
+#blog #content .date {
+  color: #6e7072;
+}
+#blog #content .tags {
+  color: #999;
+  font-size: smaller;
+}
+#blog #content .iframe, #content .image {
+  margin: 20px;
+}
+#blog #content .title {
+  margin: 20px 0;
+}
+#blog #content img {
+  max-width: 100%;
+}
+#blog .Article {
+  max-width: 55rem;
+}
+#blog .Article[data-slug='/blog/go-fonts'] {
+  font-family: Go, sans-serif;
+}
+#blog .Article[data-slug='/blog/go-fonts'] pre,
+#blog .Article[data-slug='/blog/go-fonts'] code {
+  font-family: 'Go Mono', monospace;
+}
+#blog pre, #blog code {
+  font-family: monospace;
+}
+#blog p,
+#blogindex p {
+  line-height: 1.4em;
+}
+#blogindex p.blogtitle a {
+  font-weight: bold;
+}
+#blogindex p.blogsummary {
+  margin-block-start: 0px;
+}
+#blogindex p.blogtitle {
+  margin-block-end: 0px;
+}
+#blogindex div.prevnext {
+  margin-top: 2em;
+}
+#blog .Article[data-slug='/blog/'] h1 {
+  margin-top: 1em;
+}
+
+#blog pre .highlight {
+  font-weight: bold;
+}
+
+/* Inline runnable snippets (play.js/initPlayground) */
+#blog pre,
+#content .code pre,
+#content .playground pre,
+#content .output pre {
+  margin: 0;
+  padding: 0;
+  background: none;
+  border: none;
+  outline: 0 solid transparent;
+  overflow: auto;
+}
+#content .playground .number,
+#content .code .number {
+  color: #999;
+}
+#blog pre,
+#content .code,
+#content .playground,
+#content .output {
+  width: auto;
+  margin: 1.25rem;
+  padding: 0.625rem;
+  border-radius: 0.3125rem;
+}
+#blog pre,
+#content .code,
+#content .playground {
+  background: #e9e9e9;
+}
+#content .output {
+  background: #202020;
+}
+#content .output .stdout,
+#content .output pre {
+  color: #e6e6e6;
+}
+#content .output .stderr,
+#content .output .error {
+  color: rgb(244, 74, 63);
+}
+#content .output .system,
+#content .output .exit {
+  color: rgb(255, 209, 77);
+}
+#content .buttons {
+  position: relative;
+  float: right;
+  top: -3.125rem;
+  right: 1.875rem;
+}
+#content .output .buttons {
+  top: -3.75rem;
+  right: 0;
+  height: 0;
+}
+#content .buttons .kill {
+  display: none;
+  visibility: hidden;
+}
+a.error {
+  font-weight: bold;
+  color: white;
+  background-color: darkred;
+  border-bottom-left-radius: 0.25rem;
+  border-bottom-right-radius: 0.25rem;
+  border-top-left-radius: 0.25rem;
+  border-top-right-radius: 0.25rem;
+  padding: 0.125rem 0.25rem 0.125rem 0.25rem;
+  /* TRBL */
+}
+.downloading {
+  background: #f9f9be;
+  padding: 0.625rem;
+  text-align: center;
+  border-radius: 0.3125rem;
+}
+
diff --git a/blog/_static/favicon.ico b/go.dev/_content/favicon.ico
similarity index 100%
rename from blog/_static/favicon.ico
rename to go.dev/_content/favicon.ico
Binary files differ
diff --git a/blog/_static/fonts/Go-Bold.woff b/go.dev/_content/fonts/Go-Bold.woff
similarity index 100%
rename from blog/_static/fonts/Go-Bold.woff
rename to go.dev/_content/fonts/Go-Bold.woff
Binary files differ
diff --git a/blog/_static/fonts/Go-BoldItalic.woff b/go.dev/_content/fonts/Go-BoldItalic.woff
similarity index 100%
rename from blog/_static/fonts/Go-BoldItalic.woff
rename to go.dev/_content/fonts/Go-BoldItalic.woff
Binary files differ
diff --git a/blog/_static/fonts/Go-Italic.woff b/go.dev/_content/fonts/Go-Italic.woff
similarity index 100%
rename from blog/_static/fonts/Go-Italic.woff
rename to go.dev/_content/fonts/Go-Italic.woff
Binary files differ
diff --git a/blog/_static/fonts/GoMedium-Italic.woff b/go.dev/_content/fonts/GoMedium-Italic.woff
similarity index 100%
rename from blog/_static/fonts/GoMedium-Italic.woff
rename to go.dev/_content/fonts/GoMedium-Italic.woff
Binary files differ
diff --git a/blog/_static/fonts/GoMedium.woff b/go.dev/_content/fonts/GoMedium.woff
similarity index 100%
rename from blog/_static/fonts/GoMedium.woff
rename to go.dev/_content/fonts/GoMedium.woff
Binary files differ
diff --git a/blog/_static/fonts/GoMono-Bold.woff b/go.dev/_content/fonts/GoMono-Bold.woff
similarity index 100%
rename from blog/_static/fonts/GoMono-Bold.woff
rename to go.dev/_content/fonts/GoMono-Bold.woff
Binary files differ
diff --git a/blog/_static/fonts/GoMono-BoldItalic.woff b/go.dev/_content/fonts/GoMono-BoldItalic.woff
similarity index 100%
rename from blog/_static/fonts/GoMono-BoldItalic.woff
rename to go.dev/_content/fonts/GoMono-BoldItalic.woff
Binary files differ
diff --git a/blog/_static/fonts/GoMono-Italic.woff b/go.dev/_content/fonts/GoMono-Italic.woff
similarity index 100%
rename from blog/_static/fonts/GoMono-Italic.woff
rename to go.dev/_content/fonts/GoMono-Italic.woff
Binary files differ
diff --git a/blog/_static/fonts/GoMono.woff b/go.dev/_content/fonts/GoMono.woff
similarity index 100%
rename from blog/_static/fonts/GoMono.woff
rename to go.dev/_content/fonts/GoMono.woff
Binary files differ
diff --git a/blog/_static/fonts/GoRegular.woff b/go.dev/_content/fonts/GoRegular.woff
similarity index 100%
rename from blog/_static/fonts/GoRegular.woff
rename to go.dev/_content/fonts/GoRegular.woff
Binary files differ
diff --git a/go.dev/_content/index.md b/go.dev/_content/index.md
index db1c048..2573bc6 100644
--- a/go.dev/_content/index.md
+++ b/go.dev/_content/index.md
@@ -123,7 +123,7 @@
             <li class="TestimonialsGo-quoteGroup GoCarousel-slide" id="quote_slide{{$index}}">
               <div class="TestimonialsGo-quoteSingleItem">
                 <div class="TestimonialsGo-quoteSection">
-                  <p class="TestimonialsGo-quote">{{rawhtml .quote}}</p>
+                  <p class="TestimonialsGo-quote">{{raw .quote}}</p>
                   <div class="TestimonialsGo-author">— {{.name}},
                     <span class="NoWrapSpan">{{.title}}</span>
                     <span class="NoWrapSpan"> at {{.company}}</span>
diff --git a/go.dev/_content/js/godocs.js b/go.dev/_content/js/godocs.js
new file mode 100644
index 0000000..e581cb3
--- /dev/null
+++ b/go.dev/_content/js/godocs.js
@@ -0,0 +1,381 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/* A little code to ease navigation of these documents.
+ *
+ * On window load we:
+ *  + Generate a table of contents (generateTOC)
+ *  + Bind foldable sections (bindToggles)
+ *  + Bind links to foldable sections (bindToggleLinks)
+ */
+
+(function() {
+  'use strict';
+
+  var headerEl = document.querySelector('.js-header');
+  var menuButtonEl = document.querySelector('.js-headerMenuButton');
+  menuButtonEl.addEventListener('click', function(e) {
+    e.preventDefault();
+    headerEl.classList.toggle('is-active');
+    menuButtonEl.setAttribute(
+      'aria-expanded',
+      headerEl.classList.contains('is-active')
+    );
+  });
+
+  /* Generates a table of contents: looks for h2 and h3 elements and generates
+   * links. "Decorates" the element with id=="nav" with this table of contents.
+   */
+  function generateTOC() {
+    if ($('#manual-nav').length > 0) {
+      return;
+    }
+
+    // For search, we send the toc precomputed from server-side.
+    // TODO: Ideally, this should always be precomputed for all pages, but then
+    // we need to do HTML parsing on the server-side.
+    if (location.pathname === '/search') {
+      return;
+    }
+
+    var nav = $('#nav');
+    if (nav.length === 0) {
+      return;
+    }
+
+    var toc_items = [];
+    $(nav)
+      .nextAll('h2, h3')
+      .each(function() {
+        var node = this;
+        if (node.id == '') node.id = 'tmp_' + toc_items.length;
+        var link = $('<a/>')
+          .attr('href', '#' + node.id)
+          .text($(node).text());
+        var item;
+        if ($(node).is('h2')) {
+          item = $('<dt/>');
+        } else {
+          // h3
+          item = $('<dd class="indent"/>');
+        }
+        item.append(link);
+        toc_items.push(item);
+      });
+    if (toc_items.length <= 1) {
+      return;
+    }
+    var dl1 = $('<dl/>');
+    var dl2 = $('<dl/>');
+
+    var split_index = toc_items.length / 2 + 1;
+    if (split_index < 8) {
+      split_index = toc_items.length;
+    }
+    for (var i = 0; i < split_index; i++) {
+      dl1.append(toc_items[i]);
+    }
+    for (; /* keep using i */ i < toc_items.length; i++) {
+      dl2.append(toc_items[i]);
+    }
+
+    var tocTable = $('<table class="unruled"/>').appendTo(nav);
+    var tocBody = $('<tbody/>').appendTo(tocTable);
+    var tocRow = $('<tr/>').appendTo(tocBody);
+
+    // 1st column
+    $('<td class="first"/>')
+      .appendTo(tocRow)
+      .append(dl1);
+    // 2nd column
+    $('<td/>')
+      .appendTo(tocRow)
+      .append(dl2);
+  }
+
+  function bindToggle(el) {
+    $('.toggleButton', el).click(function() {
+      if ($(this).closest('.toggle, .toggleVisible')[0] != el) {
+        // Only trigger the closest toggle header.
+        return;
+      }
+
+      if ($(el).is('.toggle')) {
+        $(el)
+          .addClass('toggleVisible')
+          .removeClass('toggle');
+      } else {
+        $(el)
+          .addClass('toggle')
+          .removeClass('toggleVisible');
+      }
+    });
+  }
+
+  function bindToggles(selector) {
+    $(selector).each(function(i, el) {
+      bindToggle(el);
+    });
+  }
+
+  function bindToggleLink(el, prefix) {
+    $(el).click(function() {
+      var href = $(el).attr('href');
+      var i = href.indexOf('#' + prefix);
+      if (i < 0) {
+        return;
+      }
+      var id = '#' + prefix + href.slice(i + 1 + prefix.length);
+      if ($(id).is('.toggle')) {
+        $(id)
+          .find('.toggleButton')
+          .first()
+          .click();
+      }
+    });
+  }
+  function bindToggleLinks(selector, prefix) {
+    $(selector).each(function(i, el) {
+      bindToggleLink(el, prefix);
+    });
+  }
+
+  function setupInlinePlayground() {
+    'use strict';
+    // Set up playground when each element is toggled.
+    $('div.play').each(function(i, el) {
+      // Set up playground for this example.
+      var setup = function() {
+        var code = $('.code', el);
+        playground({
+          codeEl: code,
+          outputEl: $('.output', el),
+          runEl: $('.run', el),
+          fmtEl: $('.fmt', el),
+          shareEl: $('.share', el),
+          shareRedirect: '//play.golang.org/p/',
+        });
+
+        // Make the code textarea resize to fit content.
+        var resize = function() {
+          code.height(0);
+          var h = code[0].scrollHeight;
+          code.height(h + 20); // minimize bouncing.
+          code.closest('.input').height(h);
+        };
+        code.on('keydown', resize);
+        code.on('keyup', resize);
+        code.keyup(); // resize now.
+      };
+
+      // If example already visible, set up playground now.
+      if ($(el).is(':visible')) {
+        setup();
+        return;
+      }
+
+      // Otherwise, set up playground when example is expanded.
+      var built = false;
+      $(el)
+        .closest('.toggle')
+        .click(function() {
+          // Only set up once.
+          if (!built) {
+            setup();
+            built = true;
+          }
+        });
+    });
+  }
+
+  // fixFocus tries to put focus to #page so that keyboard navigation works.
+  function fixFocus() {
+    var page = $('#page');
+    var topbar = $('div#topbar');
+    page.css('outline', 0); // disable outline when focused
+    page.attr('tabindex', -1); // and set tabindex so that it is focusable
+    $(window)
+      .resize(function(evt) {
+        // only focus page when the topbar is at fixed position (that is, it's in
+        // front of page, and keyboard event will go to the former by default.)
+        // by focusing page, keyboard event will go to page so that up/down arrow,
+        // space, etc. will work as expected.
+        if (topbar.css('position') == 'fixed') page.focus();
+      })
+      .resize();
+  }
+
+  function toggleHash() {
+    var id = window.location.hash.substring(1);
+    // Open all of the toggles for a particular hash.
+    var els = $(
+      document.getElementById(id),
+      $('a[name]').filter(function() {
+        return $(this).attr('name') == id;
+      })
+    );
+
+    while (els.length) {
+      for (var i = 0; i < els.length; i++) {
+        var el = $(els[i]);
+        if (el.is('.toggle')) {
+          el.find('.toggleButton')
+            .first()
+            .click();
+        }
+      }
+      els = el.parent();
+    }
+  }
+
+  function personalizeInstallInstructions() {
+    var prefix = '?download=';
+    var s = window.location.search;
+    if (s.indexOf(prefix) != 0) {
+      // No 'download' query string; detect "test" instructions from User Agent.
+      if (navigator.platform.indexOf('Win') != -1) {
+        $('.testUnix').hide();
+        $('.testWindows').show();
+      } else {
+        $('.testUnix').show();
+        $('.testWindows').hide();
+      }
+      return;
+    }
+
+    var filename = s.substr(prefix.length);
+    var filenameRE = /^go1\.\d+(\.\d+)?([a-z0-9]+)?\.([a-z0-9]+)(-[a-z0-9]+)?(-osx10\.[68])?\.([a-z.]+)$/;
+    var m = filenameRE.exec(filename);
+    if (!m) {
+      // Can't interpret file name; bail.
+      return;
+    }
+    $('.downloadFilename').text(filename);
+    $('.hideFromDownload').hide();
+
+    var os = m[3];
+    var ext = m[6];
+    if (ext != 'tar.gz') {
+      $('#tarballInstructions').hide();
+    }
+    if (os != 'darwin' || ext != 'pkg') {
+      $('#darwinPackageInstructions').hide();
+    }
+    if (os != 'windows') {
+      $('#windowsInstructions').hide();
+      $('.testUnix').show();
+      $('.testWindows').hide();
+    } else {
+      if (ext != 'msi') {
+        $('#windowsInstallerInstructions').hide();
+      }
+      if (ext != 'zip') {
+        $('#windowsZipInstructions').hide();
+      }
+      $('.testUnix').hide();
+      $('.testWindows').show();
+    }
+
+    var download = '/dl/' + filename;
+
+    var message = $(
+      '<p class="downloading">' +
+        'Your download should begin shortly. ' +
+        'If it does not, click <a>this link</a>.</p>'
+    );
+    message.find('a').attr('href', download);
+    message.insertAfter('#nav');
+
+    window.location = download;
+  }
+
+  function updateVersionTags() {
+    var v = window.goVersion;
+    if (/^go[0-9.]+$/.test(v)) {
+      $('.versionTag')
+        .empty()
+        .text(v);
+      $('.whereTag').hide();
+    }
+  }
+
+  function addPermalinks() {
+    function addPermalink(source, parent) {
+      var id = source.attr('id');
+      if (id == '' || id.indexOf('tmp_') === 0) {
+        // Auto-generated permalink.
+        return;
+      }
+      if (parent.find('> .permalink').length) {
+        // Already attached.
+        return;
+      }
+      parent
+        .append(' ')
+        .append($("<a class='permalink'>&#xb6;</a>").attr('href', '#' + id));
+    }
+
+    $('#page .container')
+      .find('h2[id], h3[id]')
+      .each(function() {
+        var el = $(this);
+        addPermalink(el, el);
+      });
+
+    $('#page .container')
+      .find('dl[id]')
+      .each(function() {
+        var el = $(this);
+        // Add the anchor to the "dt" element.
+        addPermalink(el, el.find('> dt').first());
+      });
+  }
+
+  $('.js-expandAll').click(function() {
+    if ($(this).hasClass('collapsed')) {
+      toggleExamples('toggle');
+      $(this).text('(Collapse All)');
+    } else {
+      toggleExamples('toggleVisible');
+      $(this).text('(Expand All)');
+    }
+    $(this).toggleClass('collapsed');
+  });
+
+  function toggleExamples(className) {
+    // We need to explicitly iterate through divs starting with "example_"
+    // to avoid toggling Overview and Index collapsibles.
+    $("[id^='example_']").each(function() {
+      // Check for state and click it only if required.
+      if ($(this).hasClass(className)) {
+        $(this)
+          .find('.toggleButton')
+          .first()
+          .click();
+      }
+    });
+  }
+
+  $(document).ready(function() {
+    generateTOC();
+    addPermalinks();
+    bindToggles('.toggle');
+    bindToggles('.toggleVisible');
+    bindToggleLinks('.exampleLink', 'example_');
+    bindToggleLinks('.overviewLink', '');
+    bindToggleLinks('.examplesLink', '');
+    bindToggleLinks('.indexLink', '');
+    setupInlinePlayground();
+    fixFocus();
+    toggleHash();
+    personalizeInstallInstructions();
+    updateVersionTags();
+
+    // site.html defines window.initFuncs in the <head> tag, and root.html and
+    // codewalk.js push their on-page-ready functions to the list.
+    // We execute those functions here, to avoid loading jQuery until the page
+    // content is loaded.
+    for (var i = 0; i < window.initFuncs.length; i++) window.initFuncs[i]();
+  });
+})();
diff --git a/go.dev/_content/js/jquery.js b/go.dev/_content/js/jquery.js
new file mode 100644
index 0000000..bc3fbc8
--- /dev/null
+++ b/go.dev/_content/js/jquery.js
@@ -0,0 +1,2 @@
+/*! jQuery v1.8.2 jquery.com | jquery.org/license */
+(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d<e;d++)p.event.add(b,c,h[c][d])}g.data&&(g.data=p.extend({},g.data))}function bE(a,b){var c;if(b.nodeType!==1)return;b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?(b.parentNode&&(b.outerHTML=a.outerHTML),p.support.html5Clone&&a.innerHTML&&!p.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):c==="input"&&bv.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text),b.removeAttribute(p.expando)}function bF(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bG(a){bv.test(a.type)&&(a.defaultChecked=a.checked)}function bY(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=bW.length;while(e--){b=bW[e]+c;if(b in a)return b}return d}function bZ(a,b){return a=b||a,p.css(a,"display")==="none"||!p.contains(a.ownerDocument,a)}function b$(a,b){var c,d,e=[],f=0,g=a.length;for(;f<g;f++){c=a[f];if(!c.style)continue;e[f]=p._data(c,"olddisplay"),b?(!e[f]&&c.style.display==="none"&&(c.style.display=""),c.style.display===""&&bZ(c)&&(e[f]=p._data(c,"olddisplay",cc(c.nodeName)))):(d=bH(c,"display"),!e[f]&&d!=="none"&&p._data(c,"olddisplay",d))}for(f=0;f<g;f++){c=a[f];if(!c.style)continue;if(!b||c.style.display==="none"||c.style.display==="")c.style.display=b?e[f]||"":"none"}return a}function b_(a,b,c){var d=bP.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function ca(a,b,c,d){var e=c===(d?"border":"content")?4:b==="width"?1:0,f=0;for(;e<4;e+=2)c==="margin"&&(f+=p.css(a,c+bV[e],!0)),d?(c==="content"&&(f-=parseFloat(bH(a,"padding"+bV[e]))||0),c!=="margin"&&(f-=parseFloat(bH(a,"border"+bV[e]+"Width"))||0)):(f+=parseFloat(bH(a,"padding"+bV[e]))||0,c!=="padding"&&(f+=parseFloat(bH(a,"border"+bV[e]+"Width"))||0));return f}function cb(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=!0,f=p.support.boxSizing&&p.css(a,"boxSizing")==="border-box";if(d<=0||d==null){d=bH(a,b);if(d<0||d==null)d=a.style[b];if(bQ.test(d))return d;e=f&&(p.support.boxSizingReliable||d===a.style[b]),d=parseFloat(d)||0}return d+ca(a,b,c||(f?"border":"content"),e)+"px"}function cc(a){if(bS[a])return bS[a];var b=p("<"+a+">").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write("<!doctype html><html><body>"),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bS[a]=c,c}function ci(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||ce.test(a)?d(a,e):ci(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ci(a+"["+e+"]",b[e],c,d);else d(a,b)}function cz(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h<i;h++)d=g[h],f=/^\+/.test(d),f&&(d=d.substr(1)||"*"),e=a[d]=a[d]||[],e[f?"unshift":"push"](c)}}function cA(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h,i=a[f],j=0,k=i?i.length:0,l=a===cv;for(;j<k&&(l||!h);j++)h=i[j](c,d,e),typeof h=="string"&&(!l||g[h]?h=b:(c.dataTypes.unshift(h),h=cA(a,c,d,e,h,g)));return(l||!h)&&!g["*"]&&(h=cA(a,c,d,e,"*",g)),h}function cB(a,c){var d,e,f=p.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((f[d]?a:e||(e={}))[d]=c[d]);e&&p.extend(!0,a,e)}function cC(a,c,d){var e,f,g,h,i=a.contents,j=a.dataTypes,k=a.responseFields;for(f in k)f in d&&(c[k[f]]=d[f]);while(j[0]==="*")j.shift(),e===b&&(e=a.mimeType||c.getResponseHeader("content-type"));if(e)for(f in i)if(i[f]&&i[f].test(e)){j.unshift(f);break}if(j[0]in d)g=j[0];else{for(f in d){if(!j[0]||a.converters[f+" "+j[0]]){g=f;break}h||(h=f)}g=g||h}if(g)return g!==j[0]&&j.unshift(g),d[g]}function cD(a,b){var c,d,e,f,g=a.dataTypes.slice(),h=g[0],i={},j=0;a.dataFilter&&(b=a.dataFilter(b,a.dataType));if(g[1])for(c in a.converters)i[c.toLowerCase()]=a.converters[c];for(;e=g[++j];)if(e!=="*"){if(h!=="*"&&h!==e){c=i[h+" "+e]||i["* "+e];if(!c)for(d in i){f=d.split(" ");if(f[1]===e){c=i[h+" "+f[0]]||i["* "+f[0]];if(c){c===!0?c=i[d]:i[d]!==!0&&(e=f[0],g.splice(j--,0,e));break}}}if(c!==!0)if(c&&a["throws"])b=c(b);else try{b=c(b)}catch(k){return{state:"parsererror",error:c?k:"No conversion from "+h+" to "+e}}}h=e}return{state:"success",data:b}}function cL(){try{return new a.XMLHttpRequest}catch(b){}}function cM(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function cU(){return setTimeout(function(){cN=b},0),cN=p.now()}function cV(a,b){p.each(b,function(b,c){var d=(cT[b]||[]).concat(cT["*"]),e=0,f=d.length;for(;e<f;e++)if(d[e].call(a,b,c))return})}function cW(a,b,c){var d,e=0,f=0,g=cS.length,h=p.Deferred().always(function(){delete i.elem}),i=function(){var b=cN||cU(),c=Math.max(0,j.startTime+j.duration-b),d=1-(c/j.duration||0),e=0,f=j.tweens.length;for(;e<f;e++)j.tweens[e].run(d);return h.notifyWith(a,[j,d,c]),d<1&&f?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:p.extend({},b),opts:p.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:cN||cU(),duration:c.duration,tweens:[],createTween:function(b,c,d){var e=p.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(e),e},stop:function(b){var c=0,d=b?j.tweens.length:0;for(;c<d;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;cX(k,j.opts.specialEasing);for(;e<g;e++){d=cS[e].call(j,a,k,j.opts);if(d)return d}return cV(j,k),p.isFunction(j.opts.start)&&j.opts.start.call(a,j),p.fx.timer(p.extend(i,{anim:j,queue:j.opts.queue,elem:a})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}function cX(a,b){var c,d,e,f,g;for(c in a){d=p.camelCase(c),e=b[d],f=a[c],p.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=p.cssHooks[d];if(g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}}function cY(a,b,c){var d,e,f,g,h,i,j,k,l=this,m=a.style,n={},o=[],q=a.nodeType&&bZ(a);c.queue||(j=p._queueHooks(a,"fx"),j.unqueued==null&&(j.unqueued=0,k=j.empty.fire,j.empty.fire=function(){j.unqueued||k()}),j.unqueued++,l.always(function(){l.always(function(){j.unqueued--,p.queue(a,"fx").length||j.empty.fire()})})),a.nodeType===1&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],p.css(a,"display")==="inline"&&p.css(a,"float")==="none"&&(!p.support.inlineBlockNeedsLayout||cc(a.nodeName)==="inline"?m.display="inline-block":m.zoom=1)),c.overflow&&(m.overflow="hidden",p.support.shrinkWrapBlocks||l.done(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b){f=b[d];if(cP.exec(f)){delete b[d];if(f===(q?"hide":"show"))continue;o.push(d)}}g=o.length;if(g){h=p._data(a,"fxshow")||p._data(a,"fxshow",{}),q?p(a).show():l.done(function(){p(a).hide()}),l.done(function(){var b;p.removeData(a,"fxshow",!0);for(b in n)p.style(a,b,n[b])});for(d=0;d<g;d++)e=o[d],i=l.createTween(e,q?h[e]:0),n[e]=h[e]||p.style(a,e),e in h||(h[e]=i.start,q&&(i.end=i.start,i.start=e==="width"||e==="height"?1:0))}}function cZ(a,b,c,d,e){return new cZ.prototype.init(a,b,c,d,e)}function c$(a,b){var c,d={height:a},e=0;b=b?1:0;for(;e<4;e+=2-b)c=bV[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function da(a){return p.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}var c,d,e=a.document,f=a.location,g=a.navigator,h=a.jQuery,i=a.$,j=Array.prototype.push,k=Array.prototype.slice,l=Array.prototype.indexOf,m=Object.prototype.toString,n=Object.prototype.hasOwnProperty,o=String.prototype.trim,p=function(a,b){return new p.fn.init(a,b,c)},q=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,r=/\S/,s=/\s+/,t=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,u=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:function(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.2",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);return d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i<j;i++)if((a=arguments[i])!=null)for(c in a){d=h[c],e=a[c];if(h===e)continue;k&&e&&(p.isPlainObject(e)||(f=p.isArray(e)))?(f?(f=!1,g=d&&p.isArray(d)?d:[]):g=d&&p.isPlainObject(d)?d:{},h[c]=p.extend(k,g,e)):e!==b&&(h[c]=e)}return h},p.extend({noConflict:function(b){return a.$===p&&(a.$=i),b&&a.jQuery===p&&(a.jQuery=h),p},isReady:!1,readyWait:1,holdReady:function(a){a?p.readyWait++:p.ready(!0)},ready:function(a){if(a===!0?--p.readyWait:p.isReady)return;if(!e.body)return setTimeout(p.ready,1);p.isReady=!0;if(a!==!0&&--p.readyWait>0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("Invalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f<g;)if(c.apply(a[f++],d)===!1)break}else if(h){for(e in a)if(c.call(a[e],e,a[e])===!1)break}else for(;f<g;)if(c.call(a[f],f,a[f++])===!1)break;return a},trim:o&&!o.call(" ")?function(a){return a==null?"":o.call(a)}:function(a){return a==null?"":(a+"").replace(t,"")},makeArray:function(a,b){var c,d=b||[];return a!=null&&(c=p.type(a),a.length==null||c==="string"||c==="function"||c==="regexp"||p.isWindow(a)?j.call(d,a):p.merge(d,a)),d},inArray:function(a,b,c){var d;if(b){if(l)return l.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=c.length,e=a.length,f=0;if(typeof d=="number")for(;f<d;f++)a[e++]=c[f];else while(c[f]!==b)a[e++]=c[f++];return a.length=e,a},grep:function(a,b,c){var d,e=[],f=0,g=a.length;c=!!c;for(;f<g;f++)d=!!b(a[f],f),c!==d&&e.push(a[f]);return e},map:function(a,c,d){var e,f,g=[],h=0,i=a.length,j=a instanceof p||i!==b&&typeof i=="number"&&(i>0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h<i;h++)e=c(a[h],h,d),e!=null&&(g[g.length]=e);else for(f in a)e=c(a[f],f,d),e!=null&&(g[g.length]=e);return g.concat.apply([],g)},guid:1,proxy:function(a,c){var d,e,f;return typeof c=="string"&&(d=a[c],c=a,a=d),p.isFunction(a)?(e=k.call(arguments,2),f=function(){return a.apply(c,e.concat(k.call(arguments)))},f.guid=a.guid=a.guid||p.guid++,f):b},access:function(a,c,d,e,f,g,h){var i,j=d==null,k=0,l=a.length;if(d&&typeof d=="object"){for(k in d)p.access(a,c,k,d[k],1,g,e);f=1}else if(e!==b){i=h===b&&p.isFunction(e),j&&(i?(i=c,c=function(a,b,c){return i.call(p(a),c)}):(c.call(a,e),c=null));if(c)for(;k<l;k++)c(a[k],d,i?e.call(a[k],k,c(a[k],d)):e,h);f=1}return f?a:j?c.call(a):l?c(a[0],d):g},now:function(){return(new Date).getTime()}}),p.ready.promise=function(b){if(!d){d=p.Deferred();if(e.readyState==="complete")setTimeout(p.ready,1);else if(e.addEventListener)e.addEventListener("DOMContentLoaded",D,!1),a.addEventListener("load",p.ready,!1);else{e.attachEvent("onreadystatechange",D),a.attachEvent("onload",p.ready);var c=!1;try{c=a.frameElement==null&&e.documentElement}catch(f){}c&&c.doScroll&&function g(){if(!p.isReady){try{c.doScroll("left")}catch(a){return setTimeout(g,50)}p.ready()}}()}}return d.promise(b)},p.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){E["[object "+b+"]"]=b.toLowerCase()}),c=p(e);var F={};p.Callbacks=function(a){a=typeof a=="string"?F[a]||G(a):p.extend({},a);var c,d,e,f,g,h,i=[],j=!a.once&&[],k=function(b){c=a.memory&&b,d=!0,h=f||0,f=0,g=i.length,e=!0;for(;i&&h<g;h++)if(i[h].apply(b[0],b[1])===!1&&a.stopOnFalse){c=!1;break}e=!1,i&&(j?j.length&&k(j.shift()):c?i=[]:l.disable())},l={add:function(){if(i){var b=i.length;(function d(b){p.each(b,function(b,c){var e=p.type(c);e==="function"&&(!a.unique||!l.has(c))?i.push(c):c&&c.length&&e!=="string"&&d(c)})})(arguments),e?g=i.length:c&&(f=b,k(c))}return this},remove:function(){return i&&p.each(arguments,function(a,b){var c;while((c=p.inArray(b,i,c))>-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callbacks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return a!=null?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b<d;b++)c[b]&&p.isFunction(c[b].promise)?c[b].promise().done(g(b,j,c)).fail(f.reject).progress(g(b,i,h)):--e}return e||f.resolveWith(j,c),f.promise()}}),p.support=function(){var b,c,d,f,g,h,i,j,k,l,m,n=e.createElement("div");n.setAttribute("className","t"),n.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="<div></div>",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||p.guid++:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e<f;e++)delete d[b[e]];if(!(c?K:p.isEmptyObject)(d))return}}if(!c){delete h[i].data;if(!K(h[i]))return}g?p.cleanData([a],!0):p.support.deleteExpando||h!=h.window?delete h[i]:h[i]=null},_data:function(a,b,c){return p.data(a,b,c,!0)},acceptData:function(a){var b=a.nodeName&&p.noData[a.nodeName.toLowerCase()];return!b||b!==!0&&a.getAttribute("classid")===b}}),p.fn.extend({data:function(a,c){var d,e,f,g,h,i=this[0],j=0,k=null;if(a===b){if(this.length){k=p.data(i);if(i.nodeType===1&&!p._data(i,"parsedAttrs")){f=i.attributes;for(h=f.length;j<h;j++)g=f[j].name,g.indexOf("data-")||(g=p.camelCase(g.substring(5)),J(i,g,k[g]));p._data(i,"parsedAttrs",!0)}}return k}return typeof a=="object"?this.each(function(){p.data(this,a)}):(d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!",p.access(this,function(c){if(c===b)return k=this.triggerHandler("getData"+e,[d[0]]),k===b&&i&&(k=p.data(i,a),k=J(i,a,k)),k===b&&d[1]?this.data(d[0]):k;d[1]=c,this.each(function(){var b=p(this);b.triggerHandler("setData"+e,d),p.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.length,e=c.shift(),f=p._queueHooks(a,b),g=function(){p.dequeue(a,b)};e==="inprogress"&&(e=c.shift(),d--),e&&(b==="fx"&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length<d?p.queue(this[0],a):c===b?this:this.each(function(){var b=p.queue(this,a,c);p._queueHooks(this,a),a==="fx"&&b[0]!=="inprogress"&&p.dequeue(this,a)})},dequeue:function(a){return this.each(function(){p.dequeue(this,a)})},delay:function(a,b){return a=p.fx?p.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){var d,e=1,f=p.Deferred(),g=this,h=this.length,i=function(){--e||f.resolveWith(g,[g])};typeof a!="string"&&(c=a,a=b),a=a||"fx";while(h--)d=p._data(g[h],a+"queueHooks"),d&&d.empty&&(e++,d.empty.add(i));return i(),f.promise(c)}});var L,M,N,O=/[\t\r\n]/g,P=/\r/g,Q=/^(?:button|input)$/i,R=/^(?:button|input|object|select|textarea)$/i,S=/^a(?:rea|)$/i,T=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,U=p.support.getSetAttribute;p.fn.extend({attr:function(a,b){return p.access(this,p.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.prop,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{f=" "+e.className+" ";for(g=0,h=b.length;g<h;g++)f.indexOf(" "+b[g]+" ")<0&&(f+=b[g]+" ");e.className=p.trim(f)}}}return this},removeClass:function(a){var c,d,e,f,g,h,i;if(p.isFunction(a))return this.each(function(b){p(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(s);for(h=0,i=this.length;h<i;h++){e=this[h];if(e.nodeType===1&&e.className){d=(" "+e.className+" ").replace(O," ");for(f=0,g=c.length;f<g;f++)while(d.indexOf(" "+c[f]+" ")>=0)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(O," ").indexOf(b)>=0)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.val()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c<d;c++){e=h[c];if(e.selected&&(p.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!p.nodeName(e.parentNode,"optgroup"))){b=p(e).val();if(i)return b;g.push(b)}}return i&&!g.length&&h.length?p(h[f]).val():g},set:function(a,b){var c=p.makeArray(b);return p(a).find("option").each(function(){this.selected=p.inArray(p(this).val(),c)>=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,d+""),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g<d.length;g++)e=d[g],e&&(c=p.propFix[e]||e,f=T.test(e),f||p.attr(a,e,""),a.removeAttribute(U?e:c),f&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(Q.test(a.nodeName)&&a.parentNode)p.error("type property can't be changed");else if(!p.support.radioValue&&b==="radio"&&p.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}},value:{get:function(a,b){return L&&p.nodeName(a,"button")?L.get(a,b):b in a?a.value:null},set:function(a,b,c){if(L&&p.nodeName(a,"button"))return L.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,f,g,h=a.nodeType;if(!a||h===3||h===8||h===2)return;return g=h!==1||!p.isXMLDoc(a),g&&(c=p.propFix[c]||c,f=p.propHooks[c]),d!==b?f&&"set"in f&&(e=f.set(a,d,c))!==b?e:a[c]=d:f&&"get"in f&&(e=f.get(a,c))!==null?e:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):R.test(a.nodeName)||S.test(a.nodeName)&&a.href?0:b}}}}),M={get:function(a,c){var d,e=p.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;return b===!1?p.removeAttr(a,c):(d=p.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase())),c}},U||(N={name:!0,id:!0,coords:!0},L=p.valHooks.button={get:function(a,c){var d;return d=a.getAttributeNode(c),d&&(N[c]?d.value!=="":d.specified)?d.value:b},set:function(a,b,c){var d=a.getAttributeNode(c);return d||(d=e.createAttribute(c),a.setAttributeNode(d)),d.value=b+""}},p.each(["width","height"],function(a,b){p.attrHooks[b]=p.extend(p.attrHooks[b],{set:function(a,c){if(c==="")return a.setAttribute(b,"auto"),c}})}),p.attrHooks.contenteditable={get:L.get,set:function(a,b,c){b===""&&(b="false"),L.set(a,b,c)}}),p.support.hrefNormalized||p.each(["href","src","width","height"],function(a,c){p.attrHooks[c]=p.extend(p.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),p.support.style||(p.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=b+""}}),p.support.optSelected||(p.propHooks.selected=p.extend(p.propHooks.selected,{get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}})),p.support.enctype||(p.propFix.enctype="encoding"),p.support.checkOn||p.each(["radio","checkbox"],function(){p.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),p.each(["radio","checkbox"],function(){p.valHooks[this]=p.extend(p.valHooks[this],{set:function(a,b){if(p.isArray(b))return a.checked=p.inArray(p(a).val(),b)>=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arguments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j<c.length;j++){k=W.exec(c[j])||[],l=k[1],m=(k[2]||"").split(".").sort(),r=p.event.special[l]||{},l=(f?r.delegateType:r.bindType)||l,r=p.event.special[l]||{},n=p.extend({type:l,origType:k[1],data:e,handler:d,guid:d.guid,selector:f,needsContext:f&&p.expr.match.needsContext.test(f),namespace:m.join(".")},o),q=i[l];if(!q){q=i[l]=[],q.delegateCount=0;if(!r.setup||r.setup.call(a,e,m,h)===!1)a.addEventListener?a.addEventListener(l,h,!1):a.attachEvent&&a.attachEvent("on"+l,h)}r.add&&(r.add.call(a,n),n.handler.guid||(n.handler.guid=d.guid)),f?q.splice(q.delegateCount++,0,n):q.push(n),p.event.global[l]=!0}a=null},global:{},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,q,r=p.hasData(a)&&p._data(a);if(!r||!(m=r.events))return;b=p.trim(_(b||"")).split(" ");for(f=0;f<b.length;f++){g=W.exec(b[f])||[],h=i=g[1],j=g[2];if(!h){for(h in m)p.event.remove(a,h+b[f],c,d,!0);continue}n=p.event.special[h]||{},h=(d?n.delegateType:n.bindType)||h,o=m[h]||[],k=o.length,j=j?new RegExp("(^|\\.)"+j.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(l=0;l<o.length;l++)q=o[l],(e||i===q.origType)&&(!c||c.guid===q.guid)&&(!j||j.test(q.namespace))&&(!d||d===q.selector||d==="**"&&q.selector)&&(o.splice(l--,1),q.selector&&o.delegateCount--,n.remove&&n.remove.call(a,q));o.length===0&&k!==o.length&&((!n.teardown||n.teardown.call(a,j,r.handle)===!1)&&p.removeEvent(a,h,r.handle),delete m[h])}p.isEmptyObject(m)&&(delete r.handle,p.removeData(a,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,f,g){if(!f||f.nodeType!==3&&f.nodeType!==8){var h,i,j,k,l,m,n,o,q,r,s=c.type||c,t=[];if($.test(s+p.event.triggered))return;s.indexOf("!")>=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;j<q.length&&!c.isPropagationStopped();j++)k=q[j][0],c.type=q[j][1],o=(p._data(k,"events")||{})[c.type]&&p._data(k,"handle"),o&&o.apply(k,d),o=m&&k[m],o&&p.acceptData(k)&&o.apply&&o.apply(k,d)===!1&&c.preventDefault();return c.type=s,!g&&!c.isDefaultPrevented()&&(!n._default||n._default.apply(f.ownerDocument,d)===!1)&&(s!=="click"||!p.nodeName(f,"a"))&&p.acceptData(f)&&m&&f[s]&&(s!=="focus"&&s!=="blur"||c.target.offsetWidth!==0)&&!p.isWindow(f)&&(l=f[m],l&&(f[m]=null),p.event.triggered=s,f[s](),p.event.triggered=b,l&&(f[m]=l)),c.result}return},dispatch:function(c){c=p.event.fix(c||a.event);var d,e,f,g,h,i,j,l,m,n,o=(p._data(this,"events")||{})[c.type]||[],q=o.delegateCount,r=k.call(arguments),s=!c.exclusive&&!c.namespace,t=p.event.special[c.type]||{},u=[];r[0]=c,c.delegateTarget=this;if(t.preDispatch&&t.preDispatch.call(this,c)===!1)return;if(q&&(!c.button||c.type!=="click"))for(f=c.target;f!=this;f=f.parentNode||this)if(f.disabled!==!0||c.type!=="click"){h={},j=[];for(d=0;d<q;d++)l=o[d],m=l.selector,h[m]===b&&(h[m]=l.needsContext?p(m,this).index(f)>=0:p.find(m,this,null,[f]).length),h[m]&&j.push(l);j.length&&u.push({elem:f,matches:j})}o.length>q&&u.push({elem:this,matches:o.slice(q)});for(d=0;d<u.length&&!c.isPropagationStopped();d++){i=u[d],c.currentTarget=i.elem;for(e=0;e<i.matches.length&&!c.isImmediatePropagationStopped();e++){l=i.matches[e];if(s||!c.namespace&&!l.namespace||c.namespace_re&&c.namespace_re.test(l.namespace))c.data=l.data,c.handleObj=l,g=((p.event.special[l.origType]||{}).handle||l.handler).apply(i.elem,r),g!==b&&(c.result=g,g===!1&&(c.preventDefault(),c.stopPropagation()))}}return t.postDispatch&&t.postDispatch.call(this,c),c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,c){var d,f,g,h=c.button,i=c.fromElement;return a.pageX==null&&c.clientX!=null&&(d=a.target.ownerDocument||e,f=d.documentElement,g=d.body,a.pageX=c.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=c.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?c.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0),a}},fix:function(a){if(a[p.expando])return a;var b,c,d=a,f=p.event.fixHooks[a.type]||{},g=f.props?this.props.concat(f.props):this.props;a=p.Event(d);for(b=g.length;b;)c=g[--b],a[c]=d[c];return a.target||(a.target=d.srcElement||e),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,f.filter?f.filter(a,d):a},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){p.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=p.extend(new p.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?p.event.trigger(e,null,b):p.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},p.event.handle=p.event.dispatch,p.removeEvent=e.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]=="undefined"&&(a[d]=null),a.detachEvent(d,c))},p.Event=function(a,b){if(this instanceof p.Event)a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?bb:ba):this.type=a,b&&p.extend(this,b),this.timeStamp=a&&a.timeStamp||p.now(),this[p.expando]=!0;else return new p.Event(a,b)},p.Event.prototype={preventDefault:function(){this.isDefaultPrevented=bb;var a=this.originalEvent;if(!a)return;a.preventDefault?a.preventDefault():a.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=bb;var a=this.originalEvent;if(!a)return;a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()},isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba},p.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){p.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj,g=f.selector;if(!e||e!==d&&!p.contains(d,e))a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b;return c}}}),p.support.submitBubbles||(p.event.special.submit={setup:function(){if(p.nodeName(this,"form"))return!1;p.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=p.nodeName(c,"input")||p.nodeName(c,"button")?c.form:b;d&&!p._data(d,"_submit_attached")&&(p.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),p._data(d,"_submit_attached",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&p.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(p.nodeName(this,"form"))return!1;p.event.remove(this,"._submit")}}),p.support.changeBubbles||(p.event.special.change={setup:function(){if(V.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")p.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),p.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),p.event.simulate("change",this,a,!0)});return!1}p.event.add(this,"beforeactivate._change",function(a){var b=a.target;V.test(b.nodeName)&&!p._data(b,"_change_attached")&&(p.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&p.event.simulate("change",this.parentNode,a,!0)}),p._data(b,"_change_attached",!0))})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){return p.event.remove(this,"._change"),!V.test(this.nodeName)}}),p.support.focusinBubbles||p.each({focus:"focusin",blur:"focusout"},function(a,b){var c=0,d=function(a){p.event.simulate(b,a.target,p.event.fix(a),!0)};p.event.special[b]={setup:function(){c++===0&&e.addEventListener(a,d,!0)},teardown:function(){--c===0&&e.removeEventListener(a,d,!0)}}}),p.fn.extend({on:function(a,c,d,e,f){var g,h;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(h in a)this.on(h,c,d,a[h],f);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=ba;else if(!e)return this;return f===1&&(g=e,e=function(a){return p().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=p.guid++)),this.each(function(){p.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){var e,f;if(a&&a.preventDefault&&a.handleObj)return e=a.handleObj,p(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler),this;if(typeof a=="object"){for(f in a)this.off(f,c,a[f]);return this}if(c===!1||typeof c=="function")d=c,c=b;return d===!1&&(d=ba),this.each(function(){p.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){return p(this.context).on(a,this.selector,b,c),this},die:function(a,b){return p(this.context).off(a,this.selector||"**",b),this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length===1?this.off(a,"**"):this.off(b,a||"**",c)},trigger:function(a,b){return this.each(function(){p.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return p.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||p.guid++,d=0,e=function(c){var e=(p._data(this,"lastToggle"+a.guid)||0)%d;return p._data(this,"lastToggle"+a.guid,e+1),c.preventDefault(),b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),p.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){p.fn[b]=function(a,c){return c==null&&(c=a,a=null),arguments.length>0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bc(a,b,c,d){c=c||[],b=b||r;var e,f,i,j,k=b.nodeType;if(!a||typeof a!="string")return c;if(k!==1&&k!==9)return[];i=g(b);if(!i&&!d)if(e=P.exec(a))if(j=e[1]){if(k===9){f=b.getElementById(j);if(!f||!f.parentNode)return c;if(f.id===j)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(j))&&h(b,f)&&f.id===j)return c.push(f),c}else{if(e[2])return w.apply(c,x.call(b.getElementsByTagName(a),0)),c;if((j=e[3])&&_&&b.getElementsByClassName)return w.apply(c,x.call(b.getElementsByClassName(j),0)),c}return bp(a.replace(L,"$1"),b,c,d,i)}function bd(a){return function(b){var c=b.nodeName.toLowerCase();return c==="input"&&b.type===a}}function be(a){return function(b){var c=b.nodeName.toLowerCase();return(c==="input"||c==="button")&&b.type===a}}function bf(a){return z(function(b){return b=+b,z(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function bg(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}function bh(a,b){var c,d,f,g,h,i,j,k=C[o][a];if(k)return b?0:k.slice(0);h=a,i=[],j=e.preFilter;while(h){if(!c||(d=M.exec(h)))d&&(h=h.slice(d[0].length)),i.push(f=[]);c=!1;if(d=N.exec(h))f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=d[0].replace(L," ");for(g in e.filter)(d=W[g].exec(h))&&(!j[g]||(d=j[g](d,r,!0)))&&(f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=g,c.matches=d);if(!c)break}return b?h.length:h?bc.error(a):C(a,i).slice(0)}function bi(a,b,d){var e=b.dir,f=d&&b.dir==="parentNode",g=u++;return b.first?function(b,c,d){while(b=b[e])if(f||b.nodeType===1)return a(b,c,d)}:function(b,d,h){if(!h){var i,j=t+" "+g+" ",k=j+c;while(b=b[e])if(f||b.nodeType===1){if((i=b[o])===k)return b.sizset;if(typeof i=="string"&&i.indexOf(j)===0){if(b.sizset)return b}else{b[o]=k;if(a(b,d,h))return b.sizset=!0,b;b.sizset=!1}}}else while(b=b[e])if(f||b.nodeType===1)if(a(b,d,h))return b}}function bj(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function bk(a,b,c,d,e){var f,g=[],h=0,i=a.length,j=b!=null;for(;h<i;h++)if(f=a[h])if(!c||c(f,d,e))g.push(f),j&&b.push(h);return g}function bl(a,b,c,d,e,f){return d&&!d[o]&&(d=bl(d)),e&&!e[o]&&(e=bl(e,f)),z(function(f,g,h,i){if(f&&e)return;var j,k,l,m=[],n=[],o=g.length,p=f||bo(b||"*",h.nodeType?[h]:h,[],f),q=a&&(f||!b)?bk(p,m,a,h,i):p,r=c?e||(f?a:o||d)?[]:g:q;c&&c(q,r,h,i);if(d){l=bk(r,n),d(l,[],h,i),j=l.length;while(j--)if(k=l[j])r[n[j]]=!(q[n[j]]=k)}if(f){j=a&&r.length;while(j--)if(k=r[j])f[m[j]]=!(g[m[j]]=k)}else r=bk(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):w.apply(g,r)})}function bm(a){var b,c,d,f=a.length,g=e.relative[a[0].type],h=g||e.relative[" "],i=g?1:0,j=bi(function(a){return a===b},h,!0),k=bi(function(a){return y.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==l)||((b=c).nodeType?j(a,c,d):k(a,c,d))}];for(;i<f;i++)if(c=e.relative[a[i].type])m=[bi(bj(m),c)];else{c=e.filter[a[i].type].apply(null,a[i].matches);if(c[o]){d=++i;for(;d<f;d++)if(e.relative[a[d].type])break;return bl(i>1&&bj(m),i>1&&a.slice(0,i-1).join("").replace(L,"$1"),c,i<d&&bm(a.slice(i,d)),d<f&&bm(a=a.slice(d)),d<f&&a.join(""))}m.push(c)}return bj(m)}function bn(a,b){var d=b.length>0,f=a.length>0,g=function(h,i,j,k,m){var n,o,p,q=[],s=0,u="0",x=h&&[],y=m!=null,z=l,A=h||f&&e.find.TAG("*",m&&i.parentNode||i),B=t+=z==null?1:Math.E;y&&(l=i!==r&&i,c=g.el);for(;(n=A[u])!=null;u++){if(f&&n){for(o=0;p=a[o];o++)if(p(n,i,j)){k.push(n);break}y&&(t=B,c=++g.el)}d&&((n=!p&&n)&&s--,h&&x.push(n))}s+=u;if(d&&u!==s){for(o=0;p=b[o];o++)p(x,q,i,j);if(h){if(s>0)while(u--)!x[u]&&!q[u]&&(q[u]=v.call(k));q=bk(q)}w.apply(k,q),y&&!h&&q.length>0&&s+b.length>1&&bc.uniqueSort(k)}return y&&(t=B,l=z),x};return g.el=0,d?z(g):g}function bo(a,b,c,d){var e=0,f=b.length;for(;e<f;e++)bc(a,b[e],c,d);return c}function bp(a,b,c,d,f){var g,h,j,k,l,m=bh(a),n=m.length;if(!d&&m.length===1){h=m[0]=m[0].slice(0);if(h.length>2&&(j=h[0]).type==="ID"&&b.nodeType===9&&!f&&e.relative[h[1].type]){b=e.find.ID(j.matches[0].replace(V,""),b,f)[0];if(!b)return c;a=a.slice(h.shift().length)}for(g=W.POS.test(a)?-1:h.length-1;g>=0;g--){j=h[g];if(e.relative[k=j.type])break;if(l=e.find[k])if(d=l(j.matches[0].replace(V,""),R.test(h[0].type)&&b.parentNode||b,f)){h.splice(g,1),a=d.length&&h.join("");if(!a)return w.apply(c,x.call(d,0)),c;break}}}return i(a,m)(d,b,f,c,R.test(a)),c}function bq(){}var c,d,e,f,g,h,i,j,k,l,m=!0,n="undefined",o=("sizcache"+Math.random()).replace(".",""),q=String,r=a.document,s=r.documentElement,t=0,u=0,v=[].pop,w=[].push,x=[].slice,y=[].indexOf||function(a){var b=0,c=this.length;for(;b<c;b++)if(this[b]===a)return b;return-1},z=function(a,b){return a[o]=b==null||b,a},A=function(){var a={},b=[];return z(function(c,d){return b.push(c)>e.cacheLength&&delete a[b.shift()],a[c]=d},a)},B=A(),C=A(),D=A(),E="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",G=F.replace("w","w#"),H="([*^$|!~]?=)",I="\\["+E+"*("+F+")"+E+"*(?:"+H+E+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+G+")|)|)"+E+"*\\]",J=":("+F+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+I+")|[^:]|\\\\.)*|.*))\\)|)",K=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+E+"*((?:-\\d)?\\d*)"+E+"*\\)|)(?=[^-]|$)",L=new RegExp("^"+E+"+|((?:^|[^\\\\])(?:\\\\.)*)"+E+"+$","g"),M=new RegExp("^"+E+"*,"+E+"*"),N=new RegExp("^"+E+"*([\\x20\\t\\r\\n\\f>+~])"+E+"*"),O=new RegExp(J),P=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,Q=/^:not/,R=/[\x20\t\r\n\f]*[+~]/,S=/:not\($/,T=/h\d/i,U=/input|select|textarea|button/i,V=/\\(?!\\)/g,W={ID:new RegExp("^#("+F+")"),CLASS:new RegExp("^\\.("+F+")"),NAME:new RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:new RegExp("^("+F.replace("w","w*")+")"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+J),POS:new RegExp(K,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+E+"*(even|odd|(([+-]|)(\\d*)n|)"+E+"*(?:([+-]|)"+E+"*(\\d+)|))"+E+"*\\)|)","i"),needsContext:new RegExp("^"+E+"*[>+~]|"+K,"i")},X=function(a){var b=r.createElement("div");try{return a(b)}catch(c){return!1}finally{b=null}},Y=X(function(a){return a.appendChild(r.createComment("")),!a.getElementsByTagName("*").length}),Z=X(function(a){return a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!==n&&a.firstChild.getAttribute("href")==="#"}),$=X(function(a){a.innerHTML="<select></select>";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),_=X(function(a){return a.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!a.getElementsByClassName||!a.getElementsByClassName("e").length?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length===2)}),ba=X(function(a){a.id=o+0,a.innerHTML="<a name='"+o+"'></a><div name='"+o+"'></div>",s.insertBefore(a,s.firstChild);var b=r.getElementsByName&&r.getElementsByName(o).length===2+r.getElementsByName(o+0).length;return d=!r.getElementById(o),s.removeChild(a),b});try{x.call(s.childNodes,0)[0].nodeType}catch(bb){x=function(a){var b,c=[];for(;b=this[a];a++)c.push(b);return c}}bc.matches=function(a,b){return bc(a,null,null,b)},bc.matchesSelector=function(a,b){return bc(b,null,null,[a]).length>0},f=bc.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(e===1||e===9||e===11){if(typeof a.textContent=="string")return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=f(a)}else if(e===3||e===4)return a.nodeValue}else for(;b=a[d];d++)c+=f(b);return c},g=bc.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?b.nodeName!=="HTML":!1},h=bc.contains=s.contains?function(a,b){var c=a.nodeType===9?a.documentElement:a,d=b&&b.parentNode;return a===d||!!(d&&d.nodeType===1&&c.contains&&c.contains(d))}:s.compareDocumentPosition?function(a,b){return b&&!!(a.compareDocumentPosition(b)&16)}:function(a,b){while(b=b.parentNode)if(b===a)return!0;return!1},bc.attr=function(a,b){var c,d=g(a);return d||(b=b.toLowerCase()),(c=e.attrHandle[b])?c(a):d||$?a.getAttribute(b):(c=a.getAttributeNode(b),c?typeof a[b]=="boolean"?a[b]?b:null:c.specified?c.value:null:null)},e=bc.selectors={cacheLength:50,createPseudo:z,match:W,attrHandle:Z?{}:{href:function(a){return a.getAttribute("href",2)},type:function(a){return a.getAttribute("type")}},find:{ID:d?function(a,b,c){if(typeof b.getElementById!==n&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==n&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==n&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:Y?function(a,b){if(typeof b.getElementsByTagName!==n)return b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c},NAME:ba&&function(a,b){if(typeof b.getElementsByName!==n)return b.getElementsByName(name)},CLASS:_&&function(a,b,c){if(typeof b.getElementsByClassName!==n&&!c)return b.getElementsByClassName(a)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(V,""),a[3]=(a[4]||a[5]||"").replace(V,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||bc.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&bc.error(a[0]),a},PSEUDO:function(a){var b,c;if(W.CHILD.test(a[0]))return null;if(a[3])a[2]=a[3];else if(b=a[4])O.test(b)&&(c=bh(b,!0))&&(c=b.indexOf(")",b.length-c)-b.length)&&(b=b.slice(0,c),a[0]=a[0].slice(0,c)),a[2]=b;return a.slice(0,3)}},filter:{ID:d?function(a){return a=a.replace(V,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(V,""),function(b){var c=typeof b.getAttributeNode!==n&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(V,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=B[o][a];return b||(b=B(a,new RegExp("(^|"+E+")"+a+"("+E+"|$)"))),function(a){return b.test(a.className||typeof a.getAttribute!==n&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return function(d,e){var f=bc.attr(d,a);return f==null?b==="!=":b?(f+="",b==="="?f===c:b==="!="?f!==c:b==="^="?c&&f.indexOf(c)===0:b==="*="?c&&f.indexOf(c)>-1:b==="$="?c&&f.substr(f.length-c.length)===c:b==="~="?(" "+f+" ").indexOf(c)>-1:b==="|="?f===c||f.substr(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d){return a==="nth"?function(a){var b,e,f=a.parentNode;if(c===1&&d===0)return!0;if(f){e=0;for(b=f.firstChild;b;b=b.nextSibling)if(b.nodeType===1){e++;if(a===b)break}}return e-=d,e===c||e%c===0&&e/c>=0}:function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b){var c,d=e.pseudos[a]||e.setFilters[a.toLowerCase()]||bc.error("unsupported pseudo: "+a);return d[o]?d(b):d.length>1?(c=[a,a,"",b],e.setFilters.hasOwnProperty(a.toLowerCase())?z(function(a,c){var e,f=d(a,b),g=f.length;while(g--)e=y.call(a,f[g]),a[e]=!(c[e]=f[g])}):function(a){return d(a,0,c)}):d}},pseudos:{not:z(function(a){var b=[],c=[],d=i(a.replace(L,"$1"));return d[o]?z(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)if(f=g[h])a[h]=!(b[h]=f)}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:z(function(a){return function(b){return bc(a,b).length>0}}),contains:z(function(a){return function(b){return(b.textContent||b.innerText||f(b)).indexOf(a)>-1}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!e.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.nodeType)===3||b===4)return!1;a=a.nextSibling}return!0},header:function(a){return T.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:bd("radio"),checkbox:bd("checkbox"),file:bd("file"),password:bd("password"),image:bd("image"),submit:be("submit"),reset:be("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return U.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement},first:bf(function(a,b,c){return[0]}),last:bf(function(a,b,c){return[b-1]}),eq:bf(function(a,b,c){return[c<0?c+b:c]}),even:bf(function(a,b,c){for(var d=0;d<b;d+=2)a.push(d);return a}),odd:bf(function(a,b,c){for(var d=1;d<b;d+=2)a.push(d);return a}),lt:bf(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:bf(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},j=s.compareDocumentPosition?function(a,b){return a===b?(k=!0,0):(!a.compareDocumentPosition||!b.compareDocumentPosition?a.compareDocumentPosition:a.compareDocumentPosition(b)&4)?-1:1}:function(a,b){if(a===b)return k=!0,0;if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,h=b.parentNode,i=g;if(g===h)return bg(a,b);if(!g)return-1;if(!h)return 1;while(i)e.unshift(i),i=i.parentNode;i=h;while(i)f.unshift(i),i=i.parentNode;c=e.length,d=f.length;for(var j=0;j<c&&j<d;j++)if(e[j]!==f[j])return bg(e[j],f[j]);return j===c?bg(a,f[j],-1):bg(e[j],b,1)},[0,0].sort(j),m=!k,bc.uniqueSort=function(a){var b,c=1;k=m,a.sort(j);if(k)for(;b=a[c];c++)b===a[c-1]&&a.splice(c--,1);return a},bc.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},i=bc.compile=function(a,b){var c,d=[],e=[],f=D[o][a];if(!f){b||(b=bh(a)),c=b.length;while(c--)f=bm(b[c]),f[o]?d.push(f):e.push(f);f=D(a,bn(e,d))}return f},r.querySelectorAll&&function(){var a,b=bp,c=/'|\\/g,d=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,e=[":focus"],f=[":active",":focus"],h=s.matchesSelector||s.mozMatchesSelector||s.webkitMatchesSelector||s.oMatchesSelector||s.msMatchesSelector;X(function(a){a.innerHTML="<select><option selected=''></option></select>",a.querySelectorAll("[selected]").length||e.push("\\["+E+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),X(function(a){a.innerHTML="<p test=''></p>",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+E+"*(?:\"\"|'')"),a.innerHTML="<input type='hidden'/>",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=new RegExp(e.join("|")),bp=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a))){var i,j,k=!0,l=o,m=d,n=d.nodeType===9&&a;if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){i=bh(a),(k=d.getAttribute("id"))?l=k.replace(c,"\\$&"):d.setAttribute("id",l),l="[id='"+l+"'] ",j=i.length;while(j--)i[j]=l+i[j].join("");m=R.test(a)&&d.parentNode||d,n=i.join(",")}if(n)try{return w.apply(f,x.call(m.querySelectorAll(n),0)),f}catch(p){}finally{k||d.removeAttribute("id")}}return b(a,d,f,g,h)},h&&(X(function(b){a=h.call(b,"div");try{h.call(b,"[test!='']:sizzle"),f.push("!=",J)}catch(c){}}),f=new RegExp(f.join("|")),bc.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!g(b)&&!f.test(c)&&(!e||!e.test(c)))try{var i=h.call(b,c);if(i||a||b.document&&b.document.nodeType!==11)return i}catch(j){}return bc(c,null,null,[b]).length>0})}(),e.pseudos.nth=e.pseudos.eq,e.filters=bq.prototype=e.pseudos,e.setFilters=new bq,bc.attr=p.attr,p.find=bc,p.expr=bc.selectors,p.expr[":"]=p.expr.pseudos,p.unique=bc.uniqueSort,p.text=bc.getText,p.isXMLDoc=bc.isXML,p.contains=bc.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b<c;b++)if(p.contains(h[b],this))return!0});g=this.pushStack("","find",a);for(b=0,c=this.length;b<c;b++){d=g.length,p.find(a,this[b],g);if(b>0)for(e=d;e<g.length;e++)for(f=0;f<d;f++)if(g[f]===g[e]){g.splice(e--,1);break}}return g},has:function(a){var b,c=p(a,this),d=c.length;return this.filter(function(){for(b=0;b<d;b++)if(p.contains(this,c[b]))return!0})},not:function(a){return this.pushStack(bj(this,a,!1),"not",a)},filter:function(a){return this.pushStack(bj(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?bf.test(a)?p(a,this.context).index(this[0])>=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d<e;d++){c=this[d];while(c&&c.ownerDocument&&c!==b&&c.nodeType!==11){if(g?g.index(c)>-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p.map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/<tbody/i,br=/<|&#?\w+;/,bs=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,bu=new RegExp("<(?:"+bl+")[\\s/>]","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,bz={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X<div>","</div>"]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this[0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(f){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){return bh(this[0])?this.length?this.pushStack(p(p.isFunction(a)?a():a),"replaceWith",a):this:p.isFunction(a)?this.each(function(b){var c=p(this),d=c.html();c.replaceWith(a.call(this,b,d))}):(typeof a!="string"&&(a=p(a).detach()),this.each(function(){var b=this.nextSibling,c=this.parentNode;p(this).remove(),b?p(b).before(a):p(c).append(a)}))},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){a=[].concat.apply([],a);var e,f,g,h,i=0,j=a[0],k=[],l=this.length;if(!p.support.checkClone&&l>1&&typeof j=="string"&&bw.test(j))return this.each(function(){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i<l;i++)d.call(c&&p.nodeName(this[i],"table")?bC(this[i],"tbody"):this[i],i===h?g:p.clone(g,!0,!0))}g=f=null,k.length&&p.each(k,function(a,b){b.src?p.ajax?p.ajax({url:b.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):p.error("no ajax"):p.globalEval((b.text||b.textContent||b.innerHTML||"").replace(by,"")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),p.buildFragment=function(a,c,d){var f,g,h,i=a[0];return c=c||e,c=!c.nodeType&&c[0]||c,c=c.ownerDocument||c,a.length===1&&typeof i=="string"&&i.length<512&&c===e&&i.charAt(0)==="<"&&!bt.test(i)&&(p.support.checkClone||!bw.test(i))&&(p.support.html5Clone||!bu.test(i))&&(g=!0,f=p.fragments[i],h=f!==b),f||(f=c.createDocumentFragment(),p.clean(a,c,f,d),g&&(p.fragments[i]=h&&f)),{fragment:f,cacheable:g}},p.fragments={},p.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){p.fn[a]=function(c){var d,e=0,f=[],g=p(c),h=g.length,i=this.length===1&&this[0].parentNode;if((i==null||i&&i.nodeType===11&&i.childNodes.length===1)&&h===1)return g[b](this[0]),this;for(;e<h;e++)d=(e>0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=b===e&&bA,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(f=0;(h=a[f])!=null;f++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{s=s||bk(b),l=b.createElement("div"),s.appendChild(l),h=h.replace(bo,"<$1></$2>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]==="<table>"&&!m?l.childNodes:[];for(g=n.length-1;g>=0;--g)p.nodeName(n[g],"tbody")&&!n[g].childNodes.length&&n[g].parentNode.removeChild(n[g])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l.parentNode.removeChild(l)}h.nodeType?t.push(h):p.merge(t,h)}l&&(h=l=s=null);if(!p.support.appendChecked)for(f=0;(h=t[f])!=null;f++)p.nodeName(h,"input")?bG(h):typeof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(f=0;(h=t[f])!=null;f++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[f+1,0].concat(r)),f+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.chrome?b.webkit=!0:b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^(none|table(?!-c[ea]).+)/,bO=/^margin/,bP=new RegExp("^("+q+")(.*)$","i"),bQ=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bR=new RegExp("^([-+])=("+q+")","i"),bS={},bT={position:"absolute",visibility:"hidden",display:"block"},bU={letterSpacing:0,fontWeight:400},bV=["Top","Right","Bottom","Left"],bW=["Webkit","O","Moz","ms"],bX=p.fn.toggle;p.fn.extend({css:function(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return b$(this,!0)},hide:function(){return b$(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bX.apply(this,arguments):this.each(function(){(c?a:bZ(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bY(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bR.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&isNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bY(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bU&&(f=bU[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(b,c){var d,e,f,g,h=a.getComputedStyle(b,null),i=b.style;return h&&(d=h[c],d===""&&!p.contains(b.ownerDocument,b)&&(d=p.style(b,c)),bQ.test(d)&&bO.test(c)&&(e=i.width,f=i.minWidth,g=i.maxWidth,i.minWidth=i.maxWidth=i.width=d,d=h.width,i.width=e,i.minWidth=f,i.maxWidth=g)),d}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bQ.test(e)&&!bM.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth===0&&bN.test(bH(a,"display"))?p.swap(a,bT,function(){return cb(a,b,d)}):cb(a,b,d)},set:function(a,c,d){return b_(a,c,d?ca(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMarginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bQ.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bV[d]+b]=e[d]||e[d-2]||e[0];return f}},bO.test(a)||(p.cssHooks[a+b].set=b_)});var cd=/%20/g,ce=/\[\]$/,cf=/\r?\n/g,cg=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,ch=/^(?:select|textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ch.test(this.nodeName)||cg.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(cf,"\r\n")}}):{name:b.name,value:c.replace(cf,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ci(d,a[d],c,f);return e.join("&").replace(cd,"+")};var cj,ck,cl=/#.*$/,cm=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,co=/^(?:GET|HEAD)$/,cp=/^\/\//,cq=/\?/,cr=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,cs=/([?&])_=[^&]*/,ct=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,cu=p.fn.load,cv={},cw={},cx=["*/"]+["*"];try{ck=f.href}catch(cy){ck=e.createElement("a"),ck.href="",ck=ck.href}cj=ct.exec(ck.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&cu)return cu.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):c&&typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("<div>").append(a.replace(cr,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cB(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cB(a,b),a},ajaxSettings:{url:ck,isLocal:cn.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cx},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cz(cv),ajaxTransport:cz(cw),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cC(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cD(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=(c||y)+"",k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cm.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(cl,"").replace(cp,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=ct.exec(l.url.toLowerCase())||!1,l.crossDomain=i&&i.join(":")+(i[3]?"":i[1]==="http:"?80:443)!==cj.join(":")+(cj[3]?"":cj[1]==="http:"?80:443)),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cA(cv,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!co.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cq.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cs,"$1_="+z);l.url=A+(A===l.url?(cq.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cx+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cA(cw,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cE=[],cF=/\?/,cG=/(=)\?(?=&|$)|\?\?/,cH=p.now();p.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=cE.pop()||p.expando+"_"+cH++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cG.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cG.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cG,"$1"+f):m?c.data=i.replace(cG,"$1"+f):k&&(c.url+=(cF.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cE.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cI,cJ=a.ActiveXObject?function(){for(var a in cI)cI[a](0,1)}:!1,cK=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cL()||cM()}:cL,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cJ&&delete cI[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cK,cJ&&(cI||(cI={},p(a).unload(cJ)),cI[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var cN,cO,cP=/^(?:toggle|show|hide)$/,cQ=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cR=/queueHooks$/,cS=[cY],cT={"*":[function(a,b){var c,d,e=this.createTween(a,b),f=cQ.exec(b),g=e.cur(),h=+g||0,i=1,j=20;if(f){c=+f[2],d=f[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&h){h=p.css(e.elem,a,!0)||c||1;do i=i||".5",h=h/i,p.style(e.elem,a,h+d);while(i!==(i=e.cur()/g)&&i!==1&&--j)}e.unit=d,e.start=h,e.end=f[1]?h+(f[1]+1)*c:c}return e}]};p.Animation=p.extend(cW,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d<e;d++)c=a[d],cT[c]=cT[c]||[],cT[c].unshift(b)},prefilter:function(a,b){b?cS.unshift(a):cS.push(a)}}),p.Tween=cZ,cZ.prototype={constructor:cZ,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(p.cssNumber[c]?"":"px")},cur:function(){var a=cZ.propHooks[this.prop];return a&&a.get?a.get(this):cZ.propHooks._default.get(this)},run:function(a){var b,c=cZ.propHooks[this.prop];return this.options.duration?this.pos=b=p.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):cZ.propHooks._default.set(this),this}},cZ.prototype.init.prototype=cZ.prototype,cZ.propHooks={_default:{get:function(a){var b;return a.elem[a.prop]==null||!!a.elem.style&&a.elem.style[a.prop]!=null?(b=p.css(a.elem,a.prop,!1,""),!b||b==="auto"?0:b):a.elem[a.prop]},set:function(a){p.fx.step[a.prop]?p.fx.step[a.prop](a):a.elem.style&&(a.elem.style[p.cssProps[a.prop]]!=null||p.cssHooks[a.prop])?p.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},cZ.propHooks.scrollTop=cZ.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},p.each(["toggle","show","hide"],function(a,b){var c=p.fn[b];p.fn[b]=function(d,e,f){return d==null||typeof d=="boolean"||!a&&p.isFunction(d)&&p.isFunction(e)?c.apply(this,arguments):this.animate(c$(b,!0),d,e,f)}}),p.fn.extend({fadeTo:function(a,b,c,d){return this.filter(bZ).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=p.isEmptyObject(a),f=p.speed(b,c,d),g=function(){var b=cW(this,p.extend({},a),f);e&&b.stop(!0)};return e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,c,d){var e=function(a){var b=a.stop;delete a.stop,b(d)};return typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,c=a!=null&&a+"queueHooks",f=p.timers,g=p._data(this);if(c)g[c]&&g[c].stop&&e(g[c]);else for(c in g)g[c]&&g[c].stop&&cR.test(c)&&e(g[c]);for(c=f.length;c--;)f[c].elem===this&&(a==null||f[c].queue===a)&&(f[c].anim.stop(d),b=!1,f.splice(c,1));(b||!d)&&p.dequeue(this,a)})}}),p.each({slideDown:c$("show"),slideUp:c$("hide"),slideToggle:c$("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){p.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),p.speed=function(a,b,c){var d=a&&typeof a=="object"?p.extend({},a):{complete:c||!c&&b||p.isFunction(a)&&a,duration:a,easing:c&&b||b&&!p.isFunction(b)&&b};d.duration=p.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in p.fx.speeds?p.fx.speeds[d.duration]:p.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";return d.old=d.complete,d.complete=function(){p.isFunction(d.old)&&d.old.call(this),d.queue&&p.dequeue(this,d.queue)},d},p.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},p.timers=[],p.fx=cZ.prototype.init,p.fx.tick=function(){var a,b=p.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||p.fx.stop()},p.fx.timer=function(a){a()&&p.timers.push(a)&&!cO&&(cO=setInterval(p.fx.tick,p.fx.interval))},p.fx.interval=13,p.fx.stop=function(){clearInterval(cO),cO=null},p.fx.speeds={slow:600,fast:200,_default:400},p.fx.step={},p.expr&&p.expr.filters&&(p.expr.filters.animated=function(a){return p.grep(p.timers,function(b){return a===b.elem}).length});var c_=/^(?:body|html)$/i;p.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){p.offset.setOffset(this,a,b)});var c,d,e,f,g,h,i,j={top:0,left:0},k=this[0],l=k&&k.ownerDocument;if(!l)return;return(d=l.body)===k?p.offset.bodyOffset(k):(c=l.documentElement,p.contains(c,k)?(typeof k.getBoundingClientRect!="undefined"&&(j=k.getBoundingClientRect()),e=da(l),f=c.clientTop||d.clientTop||0,g=c.clientLeft||d.clientLeft||0,h=e.pageYOffset||c.scrollTop,i=e.pageXOffset||c.scrollLeft,{top:j.top+h-f,left:j.left+i-g}):j)},p.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;return p.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(p.css(a,"marginTop"))||0,c+=parseFloat(p.css(a,"marginLeft"))||0),{top:b,left:c}},setOffset:function(a,b,c){var d=p.css(a,"position");d==="static"&&(a.style.position="relative");var e=p(a),f=e.offset(),g=p.css(a,"top"),h=p.css(a,"left"),i=(d==="absolute"||d==="fixed")&&p.inArray("auto",[g,h])>-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),p.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},p.fn.extend({position:function(){if(!this[0])return;var a=this[0],b=this.offsetParent(),c=this.offset(),d=c_.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(p.css(a,"marginTop"))||0,c.left-=parseFloat(p.css(a,"marginLeft"))||0,d.top+=parseFloat(p.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(p.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||e.body;while(a&&!c_.test(a.nodeName)&&p.css(a,"position")==="static")a=a.offsetParent;return a||e.body})}}),p.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);p.fn[a]=function(e){return p.access(this,function(a,e,f){var g=da(a);if(f===b)return g?c in g?g[c]:g.document.documentElement[e]:a[e];g?g.scrollTo(d?p(g).scrollLeft():f,d?f:p(g).scrollTop()):a[e]=f},a,e,arguments.length,null)}}),p.each({Height:"height",Width:"width"},function(a,c){p.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){p.fn[e]=function(e,f){var g=arguments.length&&(d||typeof e!="boolean"),h=d||(e===!0||f===!0?"margin":"border");return p.access(this,function(c,d,e){var f;return p.isWindow(c)?c.document.documentElement["client"+a]:c.nodeType===9?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?p.css(c,d,e,h):p.style(c,d,e,h)},c,g?e:b,g,null)}})}),a.jQuery=a.$=p,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return p})})(window);
\ No newline at end of file
diff --git a/go.dev/_content/js/play.js b/go.dev/_content/js/play.js
new file mode 100644
index 0000000..eae69eb
--- /dev/null
+++ b/go.dev/_content/js/play.js
@@ -0,0 +1,144 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+function playStart() {
+    // Insert line numbers for all playground elements.
+    $('.playground > pre.numbers, .code > pre.numbers').each(function() {
+      var $spans = $(this).find('> span');
+
+      // Compute width of number column (including trailing space).
+      var max = 0;
+      $spans.each(function() {
+        var n = $(this).attr('num')*1;
+        if (n > max) max = n;
+      });
+      var width = 2;
+      while (max > 10) {
+        max = max / 10;
+        width++;
+      }
+
+      // Insert line numbers with space padding.
+      $spans.each(function() {
+        var n = $(this).attr('num')+' ';
+        while (n.length < width) n = ' '+n;
+        $('<span class="ln">').text(n).insertBefore(this);
+      });
+    });
+
+    initPlayground(new HTTPTransport());
+}
+
+function initPlayground(transport) {
+  'use strict';
+
+  function text(node) {
+    var s = '';
+    for (var i = 0; i < node.childNodes.length; i++) {
+      var n = node.childNodes[i];
+      if (n.nodeType === 1) {
+        if (n.tagName === 'BUTTON') continue;
+        if (n.tagName === 'SPAN' && n.className === 'number') continue;
+        if (n.tagName === 'DIV' || n.tagName == 'BR') {
+          s += '\n';
+        }
+        s += text(n);
+        continue;
+      }
+      if (n.nodeType === 3) {
+        s += n.nodeValue;
+      }
+    }
+    return s.replace('\xA0', ' '); // replace non-breaking spaces
+  }
+
+  // When presenter notes are enabled, the index passed
+  // here will identify the playground to be synced
+  function init(code, index) {
+    var output = document.createElement('div');
+    var outpre = document.createElement('pre');
+    var running;
+
+    if ($ && $(output).resizable) {
+      $(output).resizable({
+        handles: 'n,w,nw',
+        minHeight: 27,
+        minWidth: 135,
+        maxHeight: 608,
+        maxWidth: 990,
+      });
+    }
+
+    function onKill() {
+      if (running) running.Kill();
+      if (window.notesEnabled) updatePlayStorage('onKill', index);
+    }
+
+    function onRun(e) {
+      var sk = e.shiftKey || localStorage.getItem('play-shiftKey') === 'true';
+      if (running) running.Kill();
+      output.style.display = 'block';
+      outpre.innerHTML = '';
+      run1.style.display = 'none';
+      var options = { Race: sk };
+      running = transport.Run(text(code), PlaygroundOutput(outpre), options);
+      if (window.notesEnabled) updatePlayStorage('onRun', index, e);
+    }
+
+    function onClose() {
+      if (running) running.Kill();
+      output.style.display = 'none';
+      run1.style.display = 'inline-block';
+      if (window.notesEnabled) updatePlayStorage('onClose', index);
+    }
+
+    if (window.notesEnabled) {
+      playgroundHandlers.onRun.push(onRun);
+      playgroundHandlers.onClose.push(onClose);
+      playgroundHandlers.onKill.push(onKill);
+    }
+
+    var run1 = document.createElement('button');
+    run1.innerHTML = 'Run';
+    run1.className = 'run';
+    run1.addEventListener('click', onRun, false);
+    var run2 = document.createElement('button');
+    run2.className = 'run';
+    run2.innerHTML = 'Run';
+    run2.addEventListener('click', onRun, false);
+    var kill = document.createElement('button');
+    kill.className = 'kill';
+    kill.innerHTML = 'Kill';
+    kill.addEventListener('click', onKill, false);
+    var close = document.createElement('button');
+    close.className = 'close';
+    close.innerHTML = 'Close';
+    close.addEventListener('click', onClose, false);
+
+    var button = document.createElement('div');
+    button.classList.add('buttons');
+    button.appendChild(run1);
+    // Hack to simulate insertAfter
+    code.parentNode.insertBefore(button, code.nextSibling);
+
+    var buttons = document.createElement('div');
+    buttons.classList.add('buttons');
+    buttons.appendChild(run2);
+    buttons.appendChild(kill);
+    buttons.appendChild(close);
+
+    output.classList.add('output');
+    output.appendChild(buttons);
+    output.appendChild(outpre);
+    output.style.display = 'none';
+    code.parentNode.insertBefore(output, button.nextSibling);
+  }
+
+  var play = document.querySelectorAll('div.playground');
+  for (var i = 0; i < play.length; i++) {
+    init(play[i], i);
+  }
+}
+
+$(function() { playStart() });
diff --git a/go.dev/_content/js/playground.js b/go.dev/_content/js/playground.js
new file mode 100644
index 0000000..97391d1
--- /dev/null
+++ b/go.dev/_content/js/playground.js
@@ -0,0 +1,575 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+In the absence of any formal way to specify interfaces in JavaScript,
+here's a skeleton implementation of a playground transport.
+
+        function Transport() {
+                // Set up any transport state (eg, make a websocket connection).
+                return {
+                        Run: function(body, output, options) {
+                                // Compile and run the program 'body' with 'options'.
+				// Call the 'output' callback to display program output.
+                                return {
+                                        Kill: function() {
+                                                // Kill the running program.
+                                        }
+                                };
+                        }
+                };
+        }
+
+	// The output callback is called multiple times, and each time it is
+	// passed an object of this form.
+        var write = {
+                Kind: 'string', // 'start', 'stdout', 'stderr', 'end'
+                Body: 'string'  // content of write or end status message
+        }
+
+	// The first call must be of Kind 'start' with no body.
+	// Subsequent calls may be of Kind 'stdout' or 'stderr'
+	// and must have a non-null Body string.
+	// The final call should be of Kind 'end' with an optional
+	// Body string, signifying a failure ("killed", for example).
+
+	// The output callback must be of this form.
+	// See PlaygroundOutput (below) for an implementation.
+        function outputCallback(write) {
+        }
+*/
+
+// HTTPTransport is the default transport.
+// enableVet enables running vet if a program was compiled and ran successfully.
+// If vet returned any errors, display them before the output of a program.
+function HTTPTransport(enableVet) {
+  'use strict';
+
+  function playback(output, data) {
+    // Backwards compatibility: default values do not affect the output.
+    var events = data.Events || [];
+    var errors = data.Errors || '';
+    var status = data.Status || 0;
+    var isTest = data.IsTest || false;
+    var testsFailed = data.TestsFailed || 0;
+
+    var timeout;
+    output({ Kind: 'start' });
+    function next() {
+      if (!events || events.length === 0) {
+        if (isTest) {
+          if (testsFailed > 0) {
+            output({
+              Kind: 'system',
+              Body:
+                '\n' +
+                testsFailed +
+                ' test' +
+                (testsFailed > 1 ? 's' : '') +
+                ' failed.',
+            });
+          } else {
+            output({ Kind: 'system', Body: '\nAll tests passed.' });
+          }
+        } else {
+          if (status > 0) {
+            output({ Kind: 'end', Body: 'status ' + status + '.' });
+          } else {
+            if (errors !== '') {
+              // errors are displayed only in the case of timeout.
+              output({ Kind: 'end', Body: errors + '.' });
+            } else {
+              output({ Kind: 'end' });
+            }
+          }
+        }
+        return;
+      }
+      var e = events.shift();
+      if (e.Delay === 0) {
+        output({ Kind: e.Kind, Body: e.Message });
+        next();
+        return;
+      }
+      timeout = setTimeout(function() {
+        output({ Kind: e.Kind, Body: e.Message });
+        next();
+      }, e.Delay / 1000000);
+    }
+    next();
+    return {
+      Stop: function() {
+        clearTimeout(timeout);
+      },
+    };
+  }
+
+  function error(output, msg) {
+    output({ Kind: 'start' });
+    output({ Kind: 'stderr', Body: msg });
+    output({ Kind: 'end' });
+  }
+
+  function buildFailed(output, msg) {
+    output({ Kind: 'start' });
+    output({ Kind: 'stderr', Body: msg });
+    output({ Kind: 'system', Body: '\nGo build failed.' });
+  }
+
+  var seq = 0;
+  return {
+    Run: function(body, output, options) {
+      seq++;
+      var cur = seq;
+      var playing;
+      $.ajax('/compile', {
+        type: 'POST',
+        data: { version: 2, body: body },
+        dataType: 'json',
+        success: function(data) {
+          if (seq != cur) return;
+          if (!data) return;
+          if (playing != null) playing.Stop();
+          if (data.Errors) {
+            if (data.Errors === 'process took too long') {
+              // Playback the output that was captured before the timeout.
+              playing = playback(output, data);
+            } else {
+              buildFailed(output, data.Errors);
+            }
+            return;
+          }
+
+          if (!enableVet) {
+            playing = playback(output, data);
+            return;
+          }
+
+          $.ajax('/vet', {
+            data: { body: body },
+            type: 'POST',
+            dataType: 'json',
+            success: function(dataVet) {
+              if (dataVet.Errors) {
+                if (!data.Events) {
+                  data.Events = [];
+                }
+                // inject errors from the vet as the first events in the output
+                data.Events.unshift({
+                  Message: 'Go vet exited.\n\n',
+                  Kind: 'system',
+                  Delay: 0,
+                });
+                data.Events.unshift({
+                  Message: dataVet.Errors,
+                  Kind: 'stderr',
+                  Delay: 0,
+                });
+              }
+              playing = playback(output, data);
+            },
+            error: function() {
+              playing = playback(output, data);
+            },
+          });
+        },
+        error: function() {
+          error(output, 'Error communicating with remote server.');
+        },
+      });
+      return {
+        Kill: function() {
+          if (playing != null) playing.Stop();
+          output({ Kind: 'end', Body: 'killed' });
+        },
+      };
+    },
+  };
+}
+
+function SocketTransport() {
+  'use strict';
+
+  var id = 0;
+  var outputs = {};
+  var started = {};
+  var websocket;
+  if (window.location.protocol == 'http:') {
+    websocket = new WebSocket('ws://' + window.location.host + '/socket');
+  } else if (window.location.protocol == 'https:') {
+    websocket = new WebSocket('wss://' + window.location.host + '/socket');
+  }
+
+  websocket.onclose = function() {
+    console.log('websocket connection closed');
+  };
+
+  websocket.onmessage = function(e) {
+    var m = JSON.parse(e.data);
+    var output = outputs[m.Id];
+    if (output === null) return;
+    if (!started[m.Id]) {
+      output({ Kind: 'start' });
+      started[m.Id] = true;
+    }
+    output({ Kind: m.Kind, Body: m.Body });
+  };
+
+  function send(m) {
+    websocket.send(JSON.stringify(m));
+  }
+
+  return {
+    Run: function(body, output, options) {
+      var thisID = id + '';
+      id++;
+      outputs[thisID] = output;
+      send({ Id: thisID, Kind: 'run', Body: body, Options: options });
+      return {
+        Kill: function() {
+          send({ Id: thisID, Kind: 'kill' });
+        },
+      };
+    },
+  };
+}
+
+function PlaygroundOutput(el) {
+  'use strict';
+
+  return function(write) {
+    if (write.Kind == 'start') {
+      el.innerHTML = '';
+      return;
+    }
+
+    var cl = 'system';
+    if (write.Kind == 'stdout' || write.Kind == 'stderr') cl = write.Kind;
+
+    var m = write.Body;
+    if (write.Kind == 'end') {
+      m = '\nProgram exited' + (m ? ': ' + m : '.');
+    }
+
+    if (m.indexOf('IMAGE:') === 0) {
+      // TODO(adg): buffer all writes before creating image
+      var url = 'data:image/png;base64,' + m.substr(6);
+      var img = document.createElement('img');
+      img.src = url;
+      el.appendChild(img);
+      return;
+    }
+
+    // ^L clears the screen.
+    var s = m.split('\x0c');
+    if (s.length > 1) {
+      el.innerHTML = '';
+      m = s.pop();
+    }
+
+    m = m.replace(/&/g, '&amp;');
+    m = m.replace(/</g, '&lt;');
+    m = m.replace(/>/g, '&gt;');
+
+    var needScroll = el.scrollTop + el.offsetHeight == el.scrollHeight;
+
+    var span = document.createElement('span');
+    span.className = cl;
+    span.innerHTML = m;
+    el.appendChild(span);
+
+    if (needScroll) el.scrollTop = el.scrollHeight - el.offsetHeight;
+  };
+}
+
+(function() {
+  function lineHighlight(error) {
+    var regex = /prog.go:([0-9]+)/g;
+    var r = regex.exec(error);
+    while (r) {
+      $('.lines div')
+        .eq(r[1] - 1)
+        .addClass('lineerror');
+      r = regex.exec(error);
+    }
+  }
+  function highlightOutput(wrappedOutput) {
+    return function(write) {
+      if (write.Body) lineHighlight(write.Body);
+      wrappedOutput(write);
+    };
+  }
+  function lineClear() {
+    $('.lineerror').removeClass('lineerror');
+  }
+
+  // opts is an object with these keys
+  //  codeEl - code editor element
+  //  outputEl - program output element
+  //  runEl - run button element
+  //  fmtEl - fmt button element (optional)
+  //  fmtImportEl - fmt "imports" checkbox element (optional)
+  //  shareEl - share button element (optional)
+  //  shareURLEl - share URL text input element (optional)
+  //  shareRedirect - base URL to redirect to on share (optional)
+  //  toysEl - toys select element (optional)
+  //  enableHistory - enable using HTML5 history API (optional)
+  //  transport - playground transport to use (default is HTTPTransport)
+  //  enableShortcuts - whether to enable shortcuts (Ctrl+S/Cmd+S to save) (default is false)
+  //  enableVet - enable running vet and displaying its errors
+  function playground(opts) {
+    var code = $(opts.codeEl);
+    var transport = opts['transport'] || new HTTPTransport(opts['enableVet']);
+    var running;
+
+    // autoindent helpers.
+    function insertTabs(n) {
+      // find the selection start and end
+      var start = code[0].selectionStart;
+      var end = code[0].selectionEnd;
+      // split the textarea content into two, and insert n tabs
+      var v = code[0].value;
+      var u = v.substr(0, start);
+      for (var i = 0; i < n; i++) {
+        u += '\t';
+      }
+      u += v.substr(end);
+      // set revised content
+      code[0].value = u;
+      // reset caret position after inserted tabs
+      code[0].selectionStart = start + n;
+      code[0].selectionEnd = start + n;
+    }
+    function autoindent(el) {
+      var curpos = el.selectionStart;
+      var tabs = 0;
+      while (curpos > 0) {
+        curpos--;
+        if (el.value[curpos] == '\t') {
+          tabs++;
+        } else if (tabs > 0 || el.value[curpos] == '\n') {
+          break;
+        }
+      }
+      setTimeout(function() {
+        insertTabs(tabs);
+      }, 1);
+    }
+
+    // NOTE(cbro): e is a jQuery event, not a DOM event.
+    function handleSaveShortcut(e) {
+      if (e.isDefaultPrevented()) return false;
+      if (!e.metaKey && !e.ctrlKey) return false;
+      if (e.key != 'S' && e.key != 's') return false;
+
+      e.preventDefault();
+
+      // Share and save
+      share(function(url) {
+        window.location.href = url + '.go?download=true';
+      });
+
+      return true;
+    }
+
+    function keyHandler(e) {
+      if (opts.enableShortcuts && handleSaveShortcut(e)) return;
+
+      if (e.keyCode == 9 && !e.ctrlKey) {
+        // tab (but not ctrl-tab)
+        insertTabs(1);
+        e.preventDefault();
+        return false;
+      }
+      if (e.keyCode == 13) {
+        // enter
+        if (e.shiftKey) {
+          // +shift
+          run();
+          e.preventDefault();
+          return false;
+        }
+        if (e.ctrlKey) {
+          // +control
+          fmt();
+          e.preventDefault();
+        } else {
+          autoindent(e.target);
+        }
+      }
+      return true;
+    }
+    code.unbind('keydown').bind('keydown', keyHandler);
+    var outdiv = $(opts.outputEl).empty();
+    var output = $('<pre/>').appendTo(outdiv);
+
+    function body() {
+      return $(opts.codeEl).val();
+    }
+    function setBody(text) {
+      $(opts.codeEl).val(text);
+    }
+    function origin(href) {
+      return ('' + href)
+        .split('/')
+        .slice(0, 3)
+        .join('/');
+    }
+
+    var pushedEmpty = window.location.pathname == '/';
+    function inputChanged() {
+      if (pushedEmpty) {
+        return;
+      }
+      pushedEmpty = true;
+      $(opts.shareURLEl).hide();
+      window.history.pushState(null, '', '/');
+    }
+    function popState(e) {
+      if (e === null) {
+        return;
+      }
+      if (e && e.state && e.state.code) {
+        setBody(e.state.code);
+      }
+    }
+    var rewriteHistory = false;
+    if (
+      window.history &&
+      window.history.pushState &&
+      window.addEventListener &&
+      opts.enableHistory
+    ) {
+      rewriteHistory = true;
+      code[0].addEventListener('input', inputChanged);
+      window.addEventListener('popstate', popState);
+    }
+
+    function setError(error) {
+      if (running) running.Kill();
+      lineClear();
+      lineHighlight(error);
+      output
+        .empty()
+        .addClass('error')
+        .text(error);
+    }
+    function loading() {
+      lineClear();
+      if (running) running.Kill();
+      output.removeClass('error').text('Waiting for remote server...');
+    }
+    function run() {
+      loading();
+      running = transport.Run(
+        body(),
+        highlightOutput(PlaygroundOutput(output[0]))
+      );
+    }
+
+    function fmt() {
+      loading();
+      var data = { body: body() };
+      if ($(opts.fmtImportEl).is(':checked')) {
+        data['imports'] = 'true';
+      }
+      $.ajax('/fmt', {
+        data: data,
+        type: 'POST',
+        dataType: 'json',
+        success: function(data) {
+          if (data.Error) {
+            setError(data.Error);
+          } else {
+            setBody(data.Body);
+            setError('');
+          }
+        },
+      });
+    }
+
+    var shareURL; // jQuery element to show the shared URL.
+    var sharing = false; // true if there is a pending request.
+    var shareCallbacks = [];
+    function share(opt_callback) {
+      if (opt_callback) shareCallbacks.push(opt_callback);
+
+      if (sharing) return;
+      sharing = true;
+
+      var sharingData = body();
+      $.ajax('/share', {
+        processData: false,
+        data: sharingData,
+        type: 'POST',
+        contentType: 'text/plain; charset=utf-8',
+        complete: function(xhr) {
+          sharing = false;
+          if (xhr.status != 200) {
+            alert('Server error; try again.');
+            return;
+          }
+          if (opts.shareRedirect) {
+            window.location = opts.shareRedirect + xhr.responseText;
+          }
+          var path = '/p/' + xhr.responseText;
+          var url = origin(window.location) + path;
+
+          for (var i = 0; i < shareCallbacks.length; i++) {
+            shareCallbacks[i](url);
+          }
+          shareCallbacks = [];
+
+          if (shareURL) {
+            shareURL
+              .show()
+              .val(url)
+              .focus()
+              .select();
+
+            if (rewriteHistory) {
+              var historyData = { code: sharingData };
+              window.history.pushState(historyData, '', path);
+              pushedEmpty = false;
+            }
+          }
+        },
+      });
+    }
+
+    $(opts.runEl).click(run);
+    $(opts.fmtEl).click(fmt);
+
+    if (
+      opts.shareEl !== null &&
+      (opts.shareURLEl !== null || opts.shareRedirect !== null)
+    ) {
+      if (opts.shareURLEl) {
+        shareURL = $(opts.shareURLEl).hide();
+      }
+      $(opts.shareEl).click(function() {
+        share();
+      });
+    }
+
+    if (opts.toysEl !== null) {
+      $(opts.toysEl).bind('change', function() {
+        var toy = $(this).val();
+        $.ajax('/doc/play/' + toy, {
+          processData: false,
+          type: 'GET',
+          complete: function(xhr) {
+            if (xhr.status != 200) {
+              alert('Server error; try again.');
+              return;
+            }
+            setBody(xhr.responseText);
+          },
+        });
+      });
+    }
+  }
+
+  window.playground = playground;
+})();
diff --git a/go.dev/_content/learn/index.md b/go.dev/_content/learn/index.md
index 2ee639a..f0e68aa 100644
--- a/go.dev/_content/learn/index.md
+++ b/go.dev/_content/learn/index.md
@@ -176,7 +176,7 @@
             <h4 class="Learn-eventName">
               <a href="{{.url}}">{{.name}}</a>
             </h4>
-            <p class="Learn-eventDescription">{{rawhtml .description}}</p>
+            <p class="Learn-eventDescription">{{raw .description}}</p>
           </div>
           <div class="Learn-eventAttendees">
             {{- with .attendees }}
@@ -205,7 +205,7 @@
     {{- end}}
     <div class="Card-content">
       <div class="Card-contentTitle">{{.title}}</div>
-      <p class="Card-contentBody">{{rawhtml .content}}</p>
+      <p class="Card-contentBody">{{raw .content}}</p>
       <div class="Card-contentCta">
         <a href="{{.url}}" target="_blank">
           <span>{{.cta}}</span>
diff --git a/go.dev/_content/site.tmpl b/go.dev/_content/site.tmpl
index e2cf7bb..678208e 100644
--- a/go.dev/_content/site.tmpl
+++ b/go.dev/_content/site.tmpl
@@ -15,6 +15,9 @@
 <meta name="theme-color" content="#00add8">
 <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Google+Sans:400,500,600|Work+Sans:400,500,600|Roboto:400,500,700|Open+Sans:Source+Code+Pro|Material+Icons">
 <link rel="stylesheet" href="/css/styles.css">
+{{if strings.HasPrefix .URL "/blog/"}}
+<link rel="stylesheet" href="/css/blogfonts.css">
+{{end}}
   <!-- 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],
diff --git a/go.dev/_content/solutions/default.tmpl b/go.dev/_content/solutions/default.tmpl
index a6cb0c7..982e1e9 100644
--- a/go.dev/_content/solutions/default.tmpl
+++ b/go.dev/_content/solutions/default.tmpl
@@ -94,7 +94,7 @@
     <div class="BackgroundQuote-author">
       <span>&mdash; {{.author}}</span>
       {{if .title}},&nbsp;
-      <span class="BackgroundQuote-title">{{rawhtml .title}}</span>
+      <span class="BackgroundQuote-title">{{raw .title}}</span>
       {{- end}}
       {{- if .company}}
       <span class="BackgroundQuote-title">&nbsp;at {{.company}}</span>
@@ -216,7 +216,7 @@
       &mdash; {{.author -}}
     </span>
     {{if .title}},&nbsp;
-      <span class="PullQuote-title">{{rawhtml .title}}</span>
+      <span class="PullQuote-title">{{raw .title}}</span>
     {{- end}}
     {{- if .company}}
       <span class="PullQuote-title">&nbsp;at {{.company -}}</span>
diff --git a/internal/blog/atom/atom.go b/internal/blog/atom/atom.go
new file mode 100644
index 0000000..efea650
--- /dev/null
+++ b/internal/blog/atom/atom.go
@@ -0,0 +1,61 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Adapted from encoding/xml/read_test.go.
+
+// Package atom defines XML data structures for an Atom feed.
+package atom // import "golang.org/x/tools/blog/atom"
+
+import (
+	"encoding/xml"
+	"time"
+)
+
+type Feed struct {
+	XMLName xml.Name `xml:"http://www.w3.org/2005/Atom feed"`
+	Title   string   `xml:"title"`
+	ID      string   `xml:"id"`
+	Link    []Link   `xml:"link"`
+	Updated TimeStr  `xml:"updated"`
+	Author  *Person  `xml:"author"`
+	Entry   []*Entry `xml:"entry"`
+}
+
+type Entry struct {
+	Title     string  `xml:"title"`
+	ID        string  `xml:"id"`
+	Link      []Link  `xml:"link"`
+	Published TimeStr `xml:"published"`
+	Updated   TimeStr `xml:"updated"`
+	Author    *Person `xml:"author"`
+	Summary   *Text   `xml:"summary"`
+	Content   *Text   `xml:"content"`
+}
+
+type Link struct {
+	Rel      string `xml:"rel,attr,omitempty"`
+	Href     string `xml:"href,attr"`
+	Type     string `xml:"type,attr,omitempty"`
+	HrefLang string `xml:"hreflang,attr,omitempty"`
+	Title    string `xml:"title,attr,omitempty"`
+	Length   uint   `xml:"length,attr,omitempty"`
+}
+
+type Person struct {
+	Name     string `xml:"name"`
+	URI      string `xml:"uri,omitempty"`
+	Email    string `xml:"email,omitempty"`
+	InnerXML string `xml:",innerxml"`
+}
+
+type Text struct {
+	Type string `xml:"type,attr"`
+	Body string `xml:",chardata"`
+}
+
+type TimeStr string
+
+func Time(t time.Time) TimeStr {
+	return TimeStr(t.Format("2006-01-02T15:04:05-07:00"))
+}
diff --git a/internal/blog/blog.go b/internal/blog/blog.go
new file mode 100644
index 0000000..9a865a2
--- /dev/null
+++ b/internal/blog/blog.go
@@ -0,0 +1,194 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package blog
+
+import (
+	"encoding/json"
+	"encoding/xml"
+	"html"
+	"io"
+	"net/http"
+	"regexp"
+	"sort"
+	"strings"
+	"time"
+
+	"golang.org/x/website/internal/blog/atom"
+	"golang.org/x/website/internal/web"
+)
+
+const maxFeed = 10
+
+// atomFeed returns the Atom feed for the go.dev blog, given the go.dev site.
+func atomFeed(site *web.Site) ([]byte, error) {
+	pages, err := feedPages(site)
+	if err != nil {
+		return nil, err
+	}
+
+	var updated time.Time
+	if len(pages) > 0 {
+		updated, _ = pages[0]["date"].(time.Time)
+	}
+
+	baseURL := "https://go.dev"
+	feed := &atom.Feed{
+		Title:   "The Go Blog",
+		ID:      "tag:blog.golang.org,2013:blog.golang.org", // keep original blog ID
+		Updated: atom.Time(updated),
+		Link: []atom.Link{{
+			Rel:  "self",
+			Href: baseURL + "/feed.atom",
+		}},
+	}
+
+	for _, p := range pages {
+		title, _ := p["title"].(string)
+		url, _ := p["URL"].(string)
+		date, _ := p["date"].(time.Time)
+		summary, _ := p["summary"].(string)
+		by, _ := p["by"].([]string)
+		content, err := site.RenderContent(p, "blogfeed.tmpl")
+		if err != nil {
+			return nil, err
+		}
+
+		e := &atom.Entry{
+			Title: title,
+			ID:    feed.ID + strings.TrimPrefix(url, "/blog"),
+			Link: []atom.Link{{
+				Rel:  "alternate",
+				Href: baseURL + url,
+			}},
+			Published: atom.Time(date),
+			Updated:   atom.Time(date),
+			Summary: &atom.Text{
+				Type: "html",
+				Body: html.EscapeString(summary),
+			},
+			Content: &atom.Text{
+				Type: "html",
+				Body: string(content),
+			},
+			Author: &atom.Person{
+				Name: authors(by),
+			},
+		}
+		feed.Entry = append(feed.Entry, e)
+	}
+
+	return xml.Marshal(feed)
+}
+
+type jsonItem struct {
+	Title   string
+	Link    string
+	Time    time.Time
+	Summary string
+	Content string
+	Author  string
+}
+
+// jsonFeed returns the JSON feed for the go.dev blog, given the go.dev site.
+func jsonFeed(site *web.Site) ([]byte, error) {
+	pages, err := feedPages(site)
+	if err != nil {
+		return nil, err
+	}
+
+	baseURL := "https://go.dev"
+	var feed []jsonItem
+	for _, p := range pages {
+		title, _ := p["title"].(string)
+		url, _ := p["URL"].(string)
+		date, _ := p["date"].(time.Time)
+		summary, _ := p["summary"].(string)
+		by, _ := p["by"].([]string)
+		content, err := site.RenderContent(p, "blogfeed.tmpl")
+		if err != nil {
+			return nil, err
+		}
+		item := jsonItem{
+			Title:   title,
+			Link:    baseURL + url,
+			Time:    date,
+			Summary: summary,
+			Content: string(content),
+			Author:  authors(by),
+		}
+		feed = append(feed, item)
+	}
+
+	return json.Marshal(feed)
+}
+
+func feedPages(site *web.Site) ([]web.Page, error) {
+	pages, err := site.Pages("/blog/*")
+	if err != nil {
+		return nil, err
+	}
+	sort.Slice(pages, func(i, j int) bool {
+		ti, _ := pages[i]["date"].(time.Time)
+		tj, _ := pages[j]["date"].(time.Time)
+		return ti.After(tj)
+	})
+	if len(pages) > maxFeed {
+		pages = pages[:maxFeed]
+	}
+	for ; len(pages) > 0; pages = pages[:len(pages)-1] {
+		last := pages[len(pages)-1]
+		t, _ := last["date"].(time.Time)
+		if !t.IsZero() {
+			break
+		}
+	}
+	return pages, nil
+}
+
+func authors(by []string) string {
+	switch len(by) {
+	case 0:
+		return ""
+	case 1:
+		return by[0]
+	case 2:
+		return by[0] + " and " + by[1]
+	default:
+		return strings.Join(by[:len(by)-1], ", ") + ", and " + by[len(by)-1]
+	}
+}
+
+var validJSONPFunc = regexp.MustCompile(`(?i)^[a-z_][a-z0-9_.]*$`)
+
+// RegisterFeeds registers the blog Atom and JSON feeds for site on mux,
+// using host as a host prefix on the registered paths.
+func RegisterFeeds(mux *http.ServeMux, host string, site *web.Site) error {
+	atom, err := atomFeed(site)
+	if err != nil {
+		return err
+	}
+	atomHandler := func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Set("Content-type", "application/atom+xml; charset=utf-8")
+		w.Write(atom)
+	}
+	mux.HandleFunc("/blog/feed.atom", atomHandler)
+	mux.HandleFunc("/blog/feeds/posts/default", atomHandler)
+
+	json, err := jsonFeed(site)
+	if err != nil {
+		return err
+	}
+	jsonHandler := func(w http.ResponseWriter, r *http.Request) {
+		if p := r.FormValue("jsonp"); validJSONPFunc.MatchString(p) {
+			w.Header().Set("Content-type", "application/javascript; charset=utf-8")
+			io.WriteString(w, p)
+		} else {
+			w.Header().Set("Content-type", "application/json; charset=utf-8")
+		}
+		w.Write(json)
+	}
+	mux.HandleFunc("/blog/.json", jsonHandler)
+	return nil
+}
diff --git a/blog/redirect.go b/internal/redirect/blog.go
similarity index 97%
rename from blog/redirect.go
rename to internal/redirect/blog.go
index 9acb2db..430987d 100644
--- a/blog/redirect.go
+++ b/internal/redirect/blog.go
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package main
+package redirect
 
-var redirects = map[string]string{
+var blogRedirects = map[string]string{
+	"/index": "all",
 	"/2010/03/go-whats-new-in-march-2010.html":               "go-whats-new-in-march-2010",
 	"/2010/04/json-rpc-tale-of-interfaces.html":              "json-rpc-tale-of-interfaces",
 	"/2010/04/third-party-libraries-goprotobuf-and.html":     "third-party-libraries-goprotobuf-and",
diff --git a/internal/redirect/redirect.go b/internal/redirect/redirect.go
index 1f0a2d4..4cd12df 100644
--- a/internal/redirect/redirect.go
+++ b/internal/redirect/redirect.go
@@ -35,6 +35,9 @@
 	for path, redirect := range redirects {
 		mux.Handle(path, Handler(redirect))
 	}
+	for path, redirect := range blogRedirects {
+		mux.Handle("go.dev/blog"+path, Handler("/blog/"+redirect))
+	}
 	// NB: /src/pkg (sans trailing slash) is the index of packages.
 	mux.HandleFunc("/src/pkg/", srcPkgHandler)
 	mux.HandleFunc("/cl/", clHandler)
@@ -92,7 +95,7 @@
 }
 
 var redirects = map[string]string{
-	"/blog":       "https://blog.golang.org",
+	"/blog":       "https://go.dev/blog",
 	"/build":      "https://build.golang.org",
 	"/change":     "https://go.googlesource.com/go",
 	"/cl":         "https://go-review.googlesource.com",
@@ -142,7 +145,7 @@
 	"play":   "https://play.golang.org/",
 	"talks":  "https://talks.golang.org/",
 	"wiki":   "https://github.com/golang/go/wiki/",
-	"blog":   "https://blog.golang.org/",
+	"blog":   "https://go.dev/blog/",
 }
 
 func Handler(target string) http.Handler {
diff --git a/internal/redirect/redirect_test.go b/internal/redirect/redirect_test.go
index 2f81769..7b74b57 100644
--- a/internal/redirect/redirect_test.go
+++ b/internal/redirect/redirect_test.go
@@ -27,9 +27,9 @@
 		"/doc/spec":    {301, "/ref/spec"},
 		"/tour":        {301, "https://tour.golang.org"},
 		"/foo":         errorResult(404),
-		"/blog":        {301, "https://blog.golang.org"},
+		"/blog":        {301, "https://go.dev/blog"},
 		"/blog/":       {302, "/blog"},
-		"/blog/go1.16": {302, "https://blog.golang.org/go1.16"},
+		"/blog/go1.16": {302, "https://go.dev/blog/go1.16"},
 
 		"/pkg/asn1":           {301, "/pkg/encoding/asn1/"},
 		"/pkg/template/parse": {301, "/pkg/text/template/parse/"},
diff --git a/internal/texthtml/texthtml.go b/internal/texthtml/texthtml.go
index 334085a..d3b1f16 100644
--- a/internal/texthtml/texthtml.go
+++ b/internal/texthtml/texthtml.go
@@ -34,7 +34,9 @@
 type Config struct {
 	Line       int       // if >= 1, number lines beginning with number Line, with <span class="ln">
 	GoComments bool      // mark comments in Go text with <span class="comment">
+	Playground bool      // format for playground sample
 	Highlight  string    // highlight matches for this regexp with <span class="highlight">
+	HL         string    // highlight lines that end with // HL (x/tools/present convention)
 	Selection  Selection // mark selected spans with <span class="selection">
 	AST        ast.Node  // link uses to declarations, assuming text is formatting of AST
 	OldDocs    bool      // emit links to ?m=old docs
@@ -49,6 +51,9 @@
 	if cfg.Highlight != "" {
 		highlights = regexpSelection(text, cfg.Highlight)
 	}
+	if cfg.HL != "" {
+		highlights = hlSelection(text, cfg.HL)
+	}
 
 	var buf bytes.Buffer
 	var idents Selection = Spans()
@@ -69,6 +74,8 @@
 		postFormatAST(&buf, cfg.AST)
 	}
 
+	trimSpaces(&buf)
+
 	if cfg.Line > 0 {
 		// Add line numbers in a separate pass.
 		old := buf.Bytes()
@@ -92,7 +99,11 @@
 			// https://github.com/webcompat/web-bugs/issues/17530#issuecomment-402675091
 			// for a fuller explanation. The solution is to add a CSS class to
 			// explicitly declare the width to be 8 characters.
-			fmt.Fprintf(&buf, `<span id="L%d" class="ln">%6d&nbsp;&nbsp;</span>`, n, n)
+			if cfg.Playground {
+				fmt.Fprintf(&buf, `<span class="number">%2d&nbsp;&nbsp;</span>`, n)
+			} else {
+				fmt.Fprintf(&buf, `<span id="L%d" class="ln">%6d&nbsp;&nbsp;</span>`, n, n)
+			}
 			n++
 			buf.Write(line)
 			buf.WriteByte('\n')
@@ -314,6 +325,28 @@
 	}
 }
 
+var hlRE = regexp.MustCompile(`(?m)\s*(.+)(\s+// (HL[a-zA-Z0-9_]*))$`)
+
+// hlSelection returns the Selection for lines ending in // hl in text,
+// also removing any // HLxxx from the text (overwriting with spaces)
+func hlSelection(text []byte, hl string) Selection {
+	lines := bytes.SplitAfter(text, []byte("\n"))
+	off := 0
+	var spans []Span
+	for _, line := range lines {
+		if m := hlRE.FindSubmatchIndex(line); m != nil {
+			if string(line[m[6]:m[7]]) == hl {
+				spans = append(spans, Span{off + m[2], off + m[3]})
+			}
+			for i := m[4]; i < m[5]; i++ {
+				line[i] = ' '
+			}
+		}
+		off += len(line)
+	}
+	return Spans(spans...)
+}
+
 // regexpSelection computes the Selection for the regular expression expr in text.
 func regexpSelection(text []byte, expr string) Selection {
 	var matches [][]int
@@ -359,3 +392,26 @@
 	}
 	template.HTMLEscape(w, text)
 }
+
+// trimSpaces removes trailing spaces at the end of each line in buf.
+func trimSpaces(buf *bytes.Buffer) {
+	data := buf.Bytes()
+	out := data[:0]
+	for len(data) > 0 {
+		j := bytes.IndexByte(data, '\n')
+		if j < 0 {
+			j = len(data)
+		}
+		var line []byte
+		line, data = data[:j], data[j:]
+		for len(line) > 0 && (line[len(line)-1] == ' ' || line[len(line)-1] == '\t') {
+			line = line[:len(line)-1]
+		}
+		out = append(out, line...)
+		if len(data) > 0 {
+			out = append(out, '\n')
+			data = data[1:]
+		}
+	}
+	buf.Truncate(len(out))
+}
diff --git a/internal/web/code.go b/internal/web/code.go
index bf18720..6dc435f 100644
--- a/internal/web/code.go
+++ b/internal/web/code.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"fmt"
+	"html"
 	"log"
 	"regexp"
 	"strings"
@@ -22,35 +23,108 @@
 		}
 	}()
 
-	btext, err := s.readFile(s.dir, file)
+	_, text, _, cfg, err := s.locate("code", file, arg...)
 	if err != nil {
 		return "", err
 	}
-	text := string(btext)
-	var command string
+	cfg.GoComments = true
+	if cfg.HL == "" {
+		cfg.HL = "HL"
+	}
+
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "<div class=\"code\">\n\n")
+	fmt.Fprintf(&buf, "<pre>")
+	// HTML-escape text and syntax-color comments like elsewhere.
+	buf.Write(texthtml.Format([]byte(text), cfg))
+	fmt.Fprintf(&buf, "</pre>\n")
+	fmt.Fprintf(&buf, "</div>\n\n")
+	return template.HTML(buf.String()), nil
+}
+
+func (s *siteDir) play(file string, arg ...interface{}) (_ template.HTML, err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("%v", r)
+		}
+	}()
+
+	before, text, after, cfg, err := s.locate("play", file, arg...)
+	if err != nil {
+		return "", err
+	}
+	cfg.Playground = true
+
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "<div class=\"playground\">\n\n")
+	if before != "" {
+		fmt.Fprintf(&buf, "<pre style=\"display: none\"><span>%s</span>\n</pre>\n", html.EscapeString(before))
+	}
+	// HTML-escape text and syntax-color comments like elsewhere.
+	fmt.Fprintf(&buf, "<pre contenteditable=\"true\" spellcheck=\"false\">")
+	buf.Write(texthtml.Format([]byte(text), cfg))
+	fmt.Fprintf(&buf, "</pre>\n")
+	if after != "" {
+		fmt.Fprintf(&buf, "<pre style=\"display: none\"><span>%s</span>\n</pre>\n", html.EscapeString(after))
+	}
+	fmt.Fprintf(&buf, "</div>\n\n")
+
+	return template.HTML(buf.String()), nil
+}
+
+func (s *siteDir) locate(verb, file string, arg ...interface{}) (before, text, after string, cfg texthtml.Config, err error) {
+	btext, err := s.readFile(s.dir, file)
+	if err != nil {
+		return
+	}
+	text = string(btext)
+	if len(arg) > 0 {
+		if s, ok := arg[len(arg)-1].(string); ok && strings.HasPrefix(s, "HL") {
+			cfg.HL = s
+			arg = arg[:len(arg)-1]
+		}
+	}
+	if len(arg) > 0 {
+		if n, ok := arg[len(arg)-1].(int); ok {
+			if n == 0 {
+				n = -1
+			}
+			cfg.Line = n
+			arg = arg[:len(arg)-1]
+		}
+	}
 	switch len(arg) {
 	case 0:
 		// text is already whole file.
-		command = fmt.Sprintf("code %q", file)
+		if cfg.Line == -1 {
+			cfg.Line = 1
+		}
 	case 1:
-		command = fmt.Sprintf("code %q %s", file, stringFor(arg[0]))
-		text = s.oneLine(file, text, arg[0])
+		var n int
+		before, text, after, n = s.oneLine(file, text, arg[0])
+		if cfg.Line == -1 {
+			cfg.Line = n
+		}
 	case 2:
-		command = fmt.Sprintf("code %q %s %s", file, stringFor(arg[0]), stringFor(arg[1]))
-		text = s.multipleLines(file, text, arg[0], arg[1])
+		var n int
+		before, text, after, n = s.multipleLines(file, text, arg[0], arg[1])
+		if cfg.Line == -1 {
+			cfg.Line = n
+		}
 	default:
-		return "", fmt.Errorf("incorrect code invocation: code %q [%v, ...] (%d arguments)", file, arg[0], len(arg))
+		err = fmt.Errorf("incorrect code invocation: %s %q [%v, ...] (%d arguments)", verb, file, arg[0], len(arg))
+		return
 	}
-	// Trim spaces from output.
+
+	// Trim leading and trailing blank lines from output.
 	text = strings.Trim(text, "\n")
+	if text != "" {
+		text += "\n"
+	}
 	// Replace tabs by spaces, which work better in HTML.
 	text = strings.Replace(text, "\t", "    ", -1)
-	var buf bytes.Buffer
-	// HTML-escape text and syntax-color comments like elsewhere.
-	buf.Write(texthtml.Format([]byte(text), texthtml.Config{GoComments: true}))
-	// Include the command as a comment.
-	text = fmt.Sprintf("<pre><!--{{%s}}\n-->%s</pre>", command, buf.Bytes())
-	return template.HTML(text), nil
+
+	return
 }
 
 // Functions in this file panic on error, but the panic is recovered
@@ -73,18 +147,19 @@
 }
 
 // oneLine returns the single line generated by a two-argument code invocation.
-func (s *Site) oneLine(file, text string, arg interface{}) string {
-	lines := strings.SplitAfter(text, "\n")
+func (s *Site) oneLine(file, body string, arg interface{}) (before, text, after string, num int) {
+	lines := strings.SplitAfter(body, "\n")
 	line, pattern, isInt := parseArg(arg, file, len(lines))
-	if isInt {
-		return lines[line-1]
+	if !isInt {
+		line = match(file, 0, lines, pattern)
 	}
-	return lines[match(file, 0, lines, pattern)-1]
+	line--
+	return strings.Join(lines[:line], ""), lines[line], strings.Join(lines[line+1:], ""), line
 }
 
 // multipleLines returns the text generated by a three-argument code invocation.
-func (s *Site) multipleLines(file, text string, arg1, arg2 interface{}) string {
-	lines := strings.SplitAfter(text, "\n")
+func (s *Site) multipleLines(file, body string, arg1, arg2 interface{}) (before, text, after string, num int) {
+	lines := strings.SplitAfter(body, "\n")
 	line1, pattern1, isInt1 := parseArg(arg1, file, len(lines))
 	line2, pattern2, isInt2 := parseArg(arg2, file, len(lines))
 	if !isInt1 {
@@ -100,7 +175,10 @@
 			lines[k] = ""
 		}
 	}
-	return strings.Join(lines[line1-1:line2], "")
+	line1--
+	return strings.Join(lines[:line1], ""),
+		strings.Join(lines[line1:line2], ""),
+		strings.Join(lines[line2:], ""), line1
 }
 
 // parseArg returns the integer or string value of the argument and tells which it is.
diff --git a/internal/web/render.go b/internal/web/render.go
index fbcc2dd..2051e43 100644
--- a/internal/web/render.go
+++ b/internal/web/render.go
@@ -8,6 +8,7 @@
 	"bytes"
 	"fmt"
 	"net/http"
+	"net/url"
 	"path"
 	"regexp"
 	"strings"
@@ -25,8 +26,18 @@
 	"golang.org/x/website/internal/tmplfunc"
 )
 
-// renderHTML renders and returns the HTML for the page.
-func (site *Site) renderHTML(p Page, r *http.Request) ([]byte, error) {
+// RenderContent returns the HTML rendering for the page using the named base template
+// (the standard base template is "site.tmpl").
+func (site *Site) RenderContent(p Page, tmpl string) (template.HTML, error) {
+	html, err := site.renderHTML(p, tmpl, &http.Request{URL: &url.URL{Path: "/missingurl"}})
+	if err != nil {
+		return "", err
+	}
+	return template.HTML(html), nil
+}
+
+// renderHTML renders and returns the Content and framed HTML for the page.
+func (site *Site) renderHTML(p Page, tmpl string, r *http.Request) ([]byte, error) {
 	// Clone p, because we are going to set its Content key-value pair.
 	p2 := make(Page)
 	for k, v := range p {
@@ -43,7 +54,7 @@
 	data, _ := p["FileData"].(string)
 
 	// Load base template.
-	base, err := site.readFile(".", "site.tmpl")
+	base, err := site.readFile(".", tmpl)
 	if err != nil {
 		return nil, err
 	}
@@ -63,13 +74,14 @@
 		"data":     sd.data,
 		"page":     sd.page,
 		"pages":    sd.pages,
+		"play":     sd.play,
 		"request":  func() *http.Request { return r },
 		"path":     func() pkgPath { return pkgPath{} },
 		"strings":  func() pkgStrings { return pkgStrings{} },
+		"file":     sd.file,
 		"first":    first,
 		"markdown": markdown,
-		"rawhtml":  rawhtml,
-		"readfile": sd.readfile,
+		"raw":      raw,
 		"yaml":     yamlFn,
 	})
 	t.Funcs(site.funcs)
diff --git a/internal/web/site.go b/internal/web/site.go
index e5a814a..cfa1768 100644
--- a/internal/web/site.go
+++ b/internal/web/site.go
@@ -172,8 +172,8 @@
 //	- [{{.title}}]({{.URL}})
 //	{{end}}
 //
-// The “{{rawhtml s}}” function converts s (a string) to type template.HTML without any escaping,
-// to allow using s as raw HTML in the final output.
+// The “{{raw s}}” function converts s (a string) to type template.HTML without any escaping,
+// to allow using s as raw Markdown or HTML in the final output.
 //
 // The “{{yaml s}}” function decodes s (a string) as YAML and returns the resulting data.
 // It is most useful for defining templates that accept YAML-structured data as a literal argument.
@@ -407,7 +407,7 @@
 }
 
 func (s *Site) servePage(w http.ResponseWriter, r *http.Request, p Page, renderingError bool) {
-	html, err := s.renderHTML(p, r)
+	html, err := s.renderHTML(p, "site.tmpl", r)
 	if err != nil {
 		s.serveErrorStatus(w, r, fmt.Errorf("template execution: %v", err), http.StatusInternalServerError, renderingError)
 		return
diff --git a/internal/web/tmpl.go b/internal/web/tmpl.go
index 2f65f35..f83f609 100644
--- a/internal/web/tmpl.go
+++ b/internal/web/tmpl.go
@@ -96,6 +96,11 @@
 	return p.page, nil
 }
 
+// Pages returns the pages found in files matching glob.
+func (site *Site) Pages(glob string) ([]Page, error) {
+	return (&siteDir{site, "."}).pages(glob)
+}
+
 // pages returns the page params for pages with urls matching glob.
 func (site *siteDir) pages(glob string) ([]Page, error) {
 	if !path.IsAbs(glob) {
@@ -128,7 +133,7 @@
 		}
 		p, err := site.openPage(file)
 		if err != nil {
-			return nil, err
+			return nil, fmt.Errorf("%s: %v", file, err)
 		}
 		out = append(out, p.page)
 	}
@@ -148,7 +153,7 @@
 	return string(data), nil
 }
 
-func rawhtml(s interface{}) template.HTML {
+func raw(s interface{}) template.HTML {
 	return template.HTML(toString(s))
 }