func (r *Runner) SaveSVG() error {
	if r.algorithm == nil {
		return errors.New("algorithm not initialized")
	}
	name := r.runtime.Dialog.SelectSaveFile("Export to SVG", "*.svg")
	r.tempPauseMutex.Lock()
	best := r.algorithm.Best().Copy()
	r.tempPauseMutex.Unlock()
	return r.logic.SaveSVG(name, best, r.pixelData)
}
SaveSVG opens a dialog to save the result of the algorithm to a SVG file
package main
import (
	"encoding/base64"
	"errors"
	"github.com/RH12503/Triangula-GUI/util"
	"github.com/RH12503/Triangula/algorithm"
	image2 "github.com/RH12503/Triangula/image"
	"github.com/wailsapp/wails"
	"image"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"strings"
	"sync"
	"time"
)
const (
	triangulated = iota
	polygonal    = iota
)
type Runner struct {
	algorithm algorithm.Algorithm  
	runtime   *wails.Runtime
	running      bool  
	runningMutex sync.Mutex
	stopped      bool  
	stoppedMutex sync.Mutex
	tempPauseMutex sync.Mutex  
	frameTime int  
	image     image.Image  
	pixelData image2.Data  
	lightMode bool  
	logic Logic
}
func (r *Runner) WailsInit(runtime *wails.Runtime) error {
	r.runtime = runtime
	r.lightMode = true
	return nil
}
func (r *Runner) Run(shape int, mutations int, mutationAmount float64, numPoints, population, cutoff, blockSize, cacheSize, threads, frameTime int) {
	switch shape {
	case triangulated:
		r.logic = TriangleLogic{}
		break
	case polygonal:
		r.logic = PolygonLogic{}
		break
	}
	if threads != 0 {
		runtime.GOMAXPROCS(threads)
	}
	if r.image == nil {
		return
	}
	if !r.Running() {
		img := image2.ToData(r.image)
		r.pixelData = img
		r.algorithm = r.logic.NewAlgorithm(img, mutations, mutationAmount, numPoints, population, cutoff, blockSize, cacheSize)
		r.stopped = false
		r.frameTime = frameTime
		r.StartAlgorithm()
		r.runtime.Events.Emit("running")  
	}
}
func (r *Runner) Stop() {
	r.runningMutex.Lock()
	r.stopped = true
	if !r.running {
		r.runtime.Events.Emit("resumed")
		r.runtime.Events.Emit("stopped")
	} else {
		r.running = false
	}
	r.runningMutex.Unlock()
}
func (r *Runner) Running() bool {
	r.runningMutex.Lock()
	defer r.runningMutex.Unlock()
	return r.running
}
func (r *Runner) SelectImage() {
	path := r.runtime.Dialog.SelectFile("Select an image", "*.jpg,*.png,*.jpeg")
	if path == "" {
		return
	}
	file, err := os.Open(path)
	if err != nil {
		log.Fatal(err)
	}
	imageFile, _, err := image.Decode(file)
	bytes, _ := ioutil.ReadFile(path)
	format := util.MimeType(bytes)
	file.Close()
	if err != nil {
		log.Fatal(err)
	}
	r.image = imageFile
	imageBase64 := "data:" + format + ";base64," + base64.StdEncoding.EncodeToString(bytes)
	r.runtime.Events.Emit("image", path, imageBase64)
}
func (r *Runner) LoadImage(name, data, base string) {
	reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(data))
	imageFile, _, err := image.Decode(reader)
	if err != nil {
		log.Fatal(err)
	}
	r.image = imageFile
	r.runtime.Events.Emit("image", name, base+data)
}