hunk.code_window: func (scheduler *TestScheduler) Run() {
   	l4g.Debug("Scheduler %v: Started", scheduler.name)
   	defer func(){
   		l4g.Debug("Scheduler %v: Finished", scheduler.name)
   		scheduler.stopped <- true
   	}()
  
hunk.labels: keep keep keep keep replace keep keep keep keep
hunk.after_edit: 	defer func() {
  
hunk.file_path: jobs/testscheduler.go
hunk.type: replace
file: package web
  
  import (
  	"bytes"
  	"fmt"
  	"image"
  	"image/color"
  	"image/draw"
  	"image/png"
  	"net/http"
  	"strconv"
  	"strings"
  
  	"code.google.com/p/freetype-go/freetype"
  	"github.com/mattermost/rsc/appfs/fs"
  	"github.com/mattermost/rsc/qr"
  	"github.com/mattermost/rsc/qr/coding"
  )
  
  func makeImage(req *http.Request, caption, font string, pt, size, border, scale int, f func(x, y int) uint32) *image.RGBA {
  	d := (size + 2*border) * scale
  	csize := 0
  	if caption != "" {
  		if pt == 0 {
  			pt = 11
  		}
  		csize = pt * 2
  	}
  	c := image.NewRGBA(image.Rect(0, 0, d, d+csize))
  
  	// white
  	u := &image.Uniform{C: color.White}
  	draw.Draw(c, c.Bounds(), u, image.ZP, draw.Src)
  
  	for y := 0; y < size; y++ {
  		for x := 0; x < size; x++ {
  			r := image.Rect((x+border)*scale, (y+border)*scale, (x+border+1)*scale, (y+border+1)*scale)
  			rgba := f(x, y)
  			u.C = color.RGBA{byte(rgba >> 24), byte(rgba >> 16), byte(rgba >> 8), byte(rgba)}
  			draw.Draw(c, r, u, image.ZP, draw.Src)
  		}
  	}
  
  	if csize != 0 {
  		if font == "" {
  			font = "data/luxisr.ttf"
  		}
  		ctxt := fs.NewContext(req)
  		dat, _, err := ctxt.Read(font)
  		if err != nil {
  			panic(err)
  		}
  		tfont, err := freetype.ParseFont(dat)
  		if err != nil {
  			panic(err)
  		}
  		ft := freetype.NewContext()
  		ft.SetDst(c)
  		ft.SetDPI(100)
  		ft.SetFont(tfont)
  		ft.SetFontSize(float64(pt))
  		ft.SetSrc(image.NewUniform(color.Black))
  		ft.SetClip(image.Rect(0, 0, 0, 0))
  		wid, err := ft.DrawString(caption, freetype.Pt(0, 0))
  		if err != nil {
  			panic(err)
  		}
  		p := freetype.Pt(d, d+3*pt/2)
  		p.X -= wid.X
  		p.X /= 2
  		ft.SetClip(c.Bounds())
  		ft.DrawString(caption, p)
  	}
  
  	return c
  }
  
  func makeFrame(req *http.Request, font string, pt, vers, l, scale, dots int) image.Image {
  	lev := coding.Level(l)
  	p, err := coding.NewPlan(coding.Version(vers), lev, 0)
  	if err != nil {
  		panic(err)
  	}
  
  	nd := p.DataBytes / p.Blocks
  	nc := p.CheckBytes / p.Blocks
  	extra := p.DataBytes - nd*p.Blocks
  
  	cap := fmt.Sprintf("QR v%d, %s", vers, lev)
  	if dots > 0 {
  		cap = fmt.Sprintf("QR v%d order, from bottom right", vers)
  	}
  	m := makeImage(req, cap, font, pt, len(p.Pixel), 0, scale, func(x, y int) uint32 {
  		pix := p.Pixel[y][x]
  		switch pix.Role() {
  		case coding.Data:
  			if dots > 0 {
  				return 0xffffffff
  			}
  			off := int(pix.Offset() / 8)
  			nd := nd
  			var i int
  			for i = 0; i < p.Blocks; i++ {
  				if i == extra {
  					nd++
  				}
  				if off < nd {
  					break
  				}
  				off -= nd
  			}
  			return blockColors[i%len(blockColors)]
  		case coding.Check:
  			if dots > 0 {
  				return 0xffffffff
  			}
  			i := (int(pix.Offset()/8) - p.DataBytes) / nc
  			return dark(blockColors[i%len(blockColors)])
  		}
  		if pix&coding.Black != 0 {
  			return 0x000000ff
  		}
  		return 0xffffffff
  	})
  
  	if dots > 0 {
  		b := m.Bounds()
  		for y := 0; y <= len(p.Pixel); y++ {
  			for x := 0; x < b.Dx(); x++ {
  				m.SetRGBA(x, y*scale-(y/len(p.Pixel)), color.RGBA{127, 127, 127, 255})
  			}
  		}
  		for x := 0; x <= len(p.Pixel); x++ {
  			for y := 0; y < b.Dx(); y++ {
  				m.SetRGBA(x*scale-(x/len(p.Pixel)), y, color.RGBA{127, 127, 127, 255})
  			}
  		}
  		order := make([]image.Point, (p.DataBytes+p.CheckBytes)*8+1)
  		for y, row := range p.Pixel {
  			for x, pix := range row {
  				if r := pix.Role(); r != coding.Data && r != coding.Check {
  					continue
  				}
  				//	draw.Draw(m, m.Bounds().Add(image.Pt(x*scale, y*scale)), dot, image.ZP, draw.Over)
  				order[pix.Offset()] = image.Point{x*scale + scale/2, y*scale + scale/2}
  			}
  		}
  
  		for mode := 0; mode < 2; mode++ {
  			for i, p := range order {
  				q := order[i+1]
  				if q.X == 0 {
  					break
  				}
  				line(m, p, q, mode)
  			}
  		}
  	}
  	return m
  }
  
  func line(m *image.RGBA, p, q image.Point, mode int) {
  	x := 0
  	y := 0
  	dx := q.X - p.X
  	dy := q.Y - p.Y
  	xsign := +1
  	ysign := +1
  	if dx < 0 {
  		xsign = -1
  		dx = -dx
  	}
  	if dy < 0 {
  		ysign = -1
  		dy = -dy
  	}
  	pt := func() {
  		switch mode {
  		case 0:
  			for dx := -2; dx <= 2; dx++ {
  				for dy := -2; dy <= 2; dy++ {
  					if dy*dx <= -4 || dy*dx >= 4 {
  						continue
  					}
  					m.SetRGBA(p.X+x*xsign+dx, p.Y+y*ysign+dy, color.RGBA{255, 192, 192, 255})
  				}
  			}
  
  		case 1:
  			m.SetRGBA(p.X+x*xsign, p.Y+y*ysign, color.RGBA{128, 0, 0, 255})
  		}
  	}
  	if dx > dy {
  		for x < dx || y < dy {
  			pt()
  			x++
  			if float64(x)*float64(dy)/float64(dx)-float64(y) > 0.5 {
  				y++
  			}
  		}
  	} else {
  		for x < dx || y < dy {
  			pt()
  			y++
  			if float64(y)*float64(dx)/float64(dy)-float64(x) > 0.5 {
  				x++
  			}
  		}
  	}
  	pt()
  }
  
  func pngEncode(c image.Image) []byte {
  	var b bytes.Buffer
  	png.Encode(&b, c)
  	return b.Bytes()
  }
  
  // Frame handles a request for a single QR frame.
  func Frame(w http.ResponseWriter, req *http.Request) {
  	arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
  	v := arg("v")
  	scale := arg("scale")
  	if scale == 0 {
  		scale = 8
  	}
  
  	w.Header().Set("Cache-Control", "public, max-age=3600")
  	w.Write(pngEncode(makeFrame(req, req.FormValue("font"), arg("pt"), v, arg("l"), scale, arg("dots"))))
  }
  
  // Frames handles a request for multiple QR frames.
  func Frames(w http.ResponseWriter, req *http.Request) {
  	vs := strings.Split(req.FormValue("v"), ",")
  
  	arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
  	scale := arg("scale")
  	if scale == 0 {
  		scale = 8
  	}
  	font := req.FormValue("font")
  	pt := arg("pt")
  	dots := arg("dots")
  
  	var images []image.Image
  	l := arg("l")
  	for _, v := range vs {
  		l := l
  		if i := strings.Index(v, "."); i >= 0 {
  			l, _ = strconv.Atoi(v[i+1:])
  			v = v[:i]
  		}
  		vv, _ := strconv.Atoi(v)
  		images = append(images, makeFrame(req, font, pt, vv, l, scale, dots))
  	}
  
  	b := images[len(images)-1].Bounds()
  
  	dx := arg("dx")
  	if dx == 0 {
  		dx = b.Dx()
  	}
  	x, y := 0, 0
  	xmax := 0
  	sep := arg("sep")
  	if sep == 0 {
  		sep = 10
  	}
  	var points []image.Point
  	for i, m := range images {
  		if x > 0 {
  			x += sep
  		}
  		if x > 0 && x+m.Bounds().Dx() > dx {
  			y += sep + images[i-1].Bounds().Dy()
  			x = 0
  		}
  		points = append(points, image.Point{x, y})
  		x += m.Bounds().Dx()
  		if x > xmax {
  			xmax = x
  		}
  
  	}
  
  	c := image.NewRGBA(image.Rect(0, 0, xmax, y+b.Dy()))
  	for i, m := range images {
  		draw.Draw(c, c.Bounds().Add(points[i]), m, image.ZP, draw.Src)
  	}
  
  	w.Header().Set("Cache-Control", "public, max-age=3600")
  	w.Write(pngEncode(c))
  }
  
  // Mask handles a request for a single QR mask.
  func Mask(w http.ResponseWriter, req *http.Request) {
  	arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
  	v := arg("v")
  	m := arg("m")
  	scale := arg("scale")
  	if scale == 0 {
  		scale = 8
  	}
  
  	w.Header().Set("Cache-Control", "public, max-age=3600")
  	w.Write(pngEncode(makeMask(req, req.FormValue("font"), arg("pt"), v, m, scale)))
  }
  
  // Masks handles a request for multiple QR masks.
  func Masks(w http.ResponseWriter, req *http.Request) {
  	arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
  	v := arg("v")
  	scale := arg("scale")
  	if scale == 0 {
  		scale = 8
  	}
  	font := req.FormValue("font")
  	pt := arg("pt")
  	var mm []image.Image
  	for m := 0; m < 8; m++ {
  		mm = append(mm, makeMask(req, font, pt, v, m, scale))
  	}
  	dx := mm[0].Bounds().Dx()
  	dy := mm[0].Bounds().Dy()
  
  	sep := arg("sep")
  	if sep == 0 {
  		sep = 10
  	}
  	c := image.NewRGBA(image.Rect(0, 0, (dx+sep)*4-sep, (dy+sep)*2-sep))
  	for m := 0; m < 8; m++ {
  		x := (m % 4) * (dx + sep)
  		y := (m / 4) * (dy + sep)
  		draw.Draw(c, c.Bounds().Add(image.Pt(x, y)), mm[m], image.ZP, draw.Src)
  	}
  
  	w.Header().Set("Cache-Control", "public, max-age=3600")
  	w.Write(pngEncode(c))
  }
  
  var maskName = []string{
  	"(x+y) % 2",
  	"y % 2",
  	"x % 3",
  	"(x+y) % 3",
  	"(y/2 + x/3) % 2",
  	"xy%2 + xy%3",
  	"(xy%2 + xy%3) % 2",
  	"(xy%3 + (x+y)%2) % 2",
  }
  
  func makeMask(req *http.Request, font string, pt int, vers, mask, scale int) image.Image {
  	p, err := coding.NewPlan(coding.Version(vers), coding.L, coding.Mask(mask))
  	if err != nil {
  		panic(err)
  	}
  	m := makeImage(req, maskName[mask], font, pt, len(p.Pixel), 0, scale, func(x, y int) uint32 {
  		pix := p.Pixel[y][x]
  		switch pix.Role() {
  		case coding.Data, coding.Check:
  			if pix&coding.Invert != 0 {
  				return 0x000000ff
  			}
  		}
  		return 0xffffffff
  	})
  	return m
  }
  
  var blockColors = []uint32{
  	0x7777ffff,
  	0xffff77ff,
  	0xff7777ff,
  	0x77ffffff,
  	0x1e90ffff,
  	0xffffe0ff,
  	0x8b6969ff,
  	0x77ff77ff,
  	0x9b30ffff,
  	0x00bfffff,
  	0x90e890ff,
  	0xfff68fff,
  	0xffec8bff,
  	0xffa07aff,
  	0xffa54fff,
  	0xeee8aaff,
  	0x98fb98ff,
  	0xbfbfbfff,
  	0x54ff9fff,
  	0xffaeb9ff,
  	0xb23aeeff,
  	0xbbffffff,
  	0x7fffd4ff,
  	0xff7a7aff,
  	0x00007fff,
  }
  
  func dark(x uint32) uint32 {
  	r, g, b, a := byte(x>>24), byte(x>>16), byte(x>>8), byte(x)
  	r = r/2 + r/4
  	g = g/2 + g/4
  	b = b/2 + b/4
  	return uint32(r)<<24 | uint32(g)<<16 | uint32(b)<<8 | uint32(a)
  }
  
  func clamp(x int) byte {
  	if x < 0 {
  		return 0
  	}
  	if x > 255 {
  		return 255
  	}
  	return byte(x)
  }
  
  func max(x, y int) int {
  	if x > y {
  		return x
  	}
  	return y
  }
  
  // Arrow handles a request for an arrow pointing in a given direction.
  func Arrow(w http.ResponseWriter, req *http.Request) {
  	arg := func(s string) int { x, _ := strconv.Atoi(req.FormValue(s)); return x }
  	dir := arg("dir")
  	size := arg("size")
  	if size == 0 {
  		size = 50
  	}
  	del := size / 10
  
  	m := image.NewRGBA(image.Rect(0, 0, size, size))
  
  	if dir == 4 {
  		draw.Draw(m, m.Bounds(), image.Black, image.ZP, draw.Src)
  		draw.Draw(m, image.Rect(5, 5, size-5, size-5), image.White, image.ZP, draw.Src)
  	}
  
  	pt := func(x, y int, c color.RGBA) {
  		switch dir {
  		case 0:
  			m.SetRGBA(x, y, c)
  		case 1:
  			m.SetRGBA(y, size-1-x, c)
  		case 2:
  			m.SetRGBA(size-1-x, size-1-y, c)
  		case 3:
  			m.SetRGBA(size-1-y, x, c)
  		}
  	}
  
  	for y := 0; y < size/2; y++ {
  		for x := 0; x < del && x < y; x++ {
  			pt(x, y, color.RGBA{0, 0, 0, 255})
  		}
  		for x := del; x < y-del; x++ {
  			pt(x, y, color.RGBA{128, 128, 255, 255})
  		}
  		for x := max(y-del, 0); x <= y; x++ {
  			pt(x, y, color.RGBA{0, 0, 0, 255})
  		}
  	}
  	for y := size / 2; y < size; y++ {
  		for x := 0; x < del && x < size-1-y; x++ {
  			pt(x, y, color.RGBA{0, 0, 0, 255})
  		}
  		for x := del; x < size-1-y-del; x++ {
  			pt(x, y, color.RGBA{128, 128, 192, 255})
  		}
  		for x := max(size-1-y-del, 0); x <= size-1-y; x++ {
  			pt(x, y, color.RGBA{0, 0, 0, 255})
  		}
  	}
  
  	w.Header().Set("Cache-Control", "public, max-age=3600")
  	w.Write(pngEncode(m))
  }
  
  // Encode encodes a string using the given version, level, and mask.
  func Encode(w http.ResponseWriter, req *http.Request) {
  	val := func(s string) int {
  		v, _ := strconv.Atoi(req.FormValue(s))
  		return v
  	}
  
  	l := coding.Level(val("l"))
  	v := coding.Version(val("v"))
  	enc := coding.String(req.FormValue("t"))
  	m := coding.Mask(val("m"))
  	
  	p, err := coding.NewPlan(v, l, m)
  	if err != nil {
  		panic(err)
  	}
  	cc, err := p.Encode(enc)
  	if err != nil {
  		panic(err)
  	}
  	
  	c := &qr.Code{Bitmap: cc.Bitmap, Size: cc.Size, Stride: cc.Stride, Scale: 8}
  	w.Header().Set("Content-Type", "image/png")
  	w.Header().Set("Cache-Control", "public, max-age=3600")
  	w.Write(c.PNG())
  }
  
  