├── .gitignore ├── main.wasm ├── assets ├── app.js └── wasm_exec.js ├── README.md ├── LICENSE ├── image ├── visualization.go └── draw.go ├── digits ├── parser_test.go └── parser.go ├── main.go ├── index.html └── resources ├── e.txt ├── phi.txt └── pi.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | goexec 3 | -------------------------------------------------------------------------------- /main.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hugolgst/digart/HEAD/main.wasm -------------------------------------------------------------------------------- /assets/app.js: -------------------------------------------------------------------------------- 1 | // Delete the notification 2 | document.getElementById("notification-delete").onclick = function() { 3 | document.getElementById("notification-modal").className = "modal" 4 | } 5 | 6 | // Read the content of a file and put it into the number field 7 | document.getElementById("read").onclick = function() { 8 | const input = document.querySelector("input[type=file]") 9 | if (input.files.length === 0) { 10 | console.log('No file selected.') 11 | return 12 | } 13 | 14 | const reader = new FileReader(); 15 | reader.onload = function fileReadCompleted() { 16 | let content = reader.result.substring( 17 | 0, 18 | parseInt(document.getElementById("digits").value) 19 | ) 20 | 21 | document.getElementById("number").value = content 22 | }; 23 | reader.readAsText(input.files[0]); 24 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |
3 | Digart pi 4 |
5 |

6 | 7 |

circle visualization of a number's digits in Go

8 | 9 |

10 | 11 | 12 |

13 | 14 |

15 | Introduction — 16 | License 17 |

18 | 19 | ## Introduction 20 | In the image below, each dot represents a decimal which is in a segment that represents the previous decimal, its position is its position in π. 21 | 22 | The website is using JS and WebAssembly 23 | 24 | ## License 25 | [MIT](https://github.com/hugolgst/digart/blob/master/LICENSE) 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-Present Hugo Lageneste 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /image/visualization.go: -------------------------------------------------------------------------------- 1 | package image 2 | 3 | import ( 4 | "fmt" 5 | "image" 6 | "image/color" 7 | "math" 8 | ) 9 | 10 | // DrawData draws in the given image all the points for the parsed decimals 11 | func DrawData(img image.RGBA, parsedDigits [][][]int, radius, image int) { 12 | fmt.Println("Drawing the data") 13 | 14 | // Arbitrary number of iterations 15 | iterations := 80 16 | 17 | // Iterate through segments 18 | for segmentIndex, segment := range parsedDigits { 19 | // Browse all the lines 20 | for line := 0; line < len(segment); line++ { 21 | // Calculate the radius for the actual line 22 | r := float64(radius*5/4 + line * radius/15) 23 | 24 | t := math.Pi/float64(iterations) 25 | 26 | // Draw the points 27 | for i := 0; i < int(iterations*2); i++ { 28 | // Calculate the coordinates 29 | x1 := r*math.Cos(t)+float64(image/2) 30 | y1 := r*math.Sin(t)+float64(image/2) 31 | 32 | t += math.Pi/float64(iterations) 33 | size := iterations/5 34 | 35 | // Only iterate through the wanted part of the circle 36 | if i < segmentIndex*size || i >= size*(segmentIndex+1) + len(segment[line]) - size { 37 | continue 38 | } 39 | 40 | // Choose the correct color 41 | colorIndex := segment[line][i%size] 42 | var c color.RGBA 43 | if colorIndex == -1 { 44 | c = color.RGBA{A: 255} 45 | } else { 46 | c = colors[colorIndex] 47 | } 48 | 49 | // Then draw the point 50 | DrawPoint(img, int(x1), int(y1), 6, c) 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /digits/parser_test.go: -------------------------------------------------------------------------------- 1 | package digits 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestParseDigits(t *testing.T) { 9 | number := "3141592653589" 10 | digits := ParseDigits(number) 11 | excepted := [][][]int{ 12 | nil, 13 | {{-1, 4, -1, 5, -1, -1, -1, -1, -1, -1}}, 14 | {{-1, -1, -1, -1, -1, -1, 6, -1, -1, -1}}, 15 | {{1, -1, -1, -1, -1, -1, -1, -1, -1, 5}}, 16 | {{-1, -1, 1, -1, -1, -1, -1, -1, -1, -1}}, 17 | {{8, -1, -1, -1, 9, -1, -1, -1, 3, -1}}, 18 | {{-1, -1, -1, -1, -1, -1, -1, 5, -1, -1}}, 19 | nil, 20 | {{-1, 9, -1, -1, -1, -1, -1, -1, -1, -1}}, 21 | {{-1, -1, -1, -1, -1, 2, -1, -1, -1, -1}}, 22 | } 23 | 24 | if !reflect.DeepEqual(digits, excepted) { 25 | t.Errorf("ParseDigits failed, excepted %d got %d.", excepted, digits) 26 | } 27 | } 28 | 29 | func TestGenerateSegment(t *testing.T) { 30 | var segments [][]int 31 | position, value := 2, 5 32 | 33 | segments = GenerateSegment(segments, position, value) 34 | excepted := [][]int{{-1, -1, 5, -1, -1, -1, -1, -1, -1, -1}} 35 | 36 | if !reflect.DeepEqual(segments, excepted) { 37 | t.Errorf("GenerateSegment failed, excepted %d got %d.", excepted, segments) 38 | } 39 | 40 | position, value = 2, 8 41 | segments = GenerateSegment(segments, position, value) 42 | excepted = append(excepted, []int{-1, -1, 8, -1, -1, -1, -1, -1, -1, -1}) 43 | 44 | if !reflect.DeepEqual(segments, excepted) { 45 | t.Errorf("GenerateSegment failed, excepted %d got %d.", excepted, segments) 46 | } 47 | } 48 | 49 | func TestMakeIntArray(t *testing.T) { 50 | array := MakeIntArray(10) 51 | excepted := []int{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1} 52 | 53 | if !reflect.DeepEqual(array, excepted) { 54 | t.Errorf("MakeIntArray failed, excepted %d got %d.", excepted, array) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /image/draw.go: -------------------------------------------------------------------------------- 1 | package image 2 | 3 | import ( 4 | "fmt" 5 | "image" 6 | "image/color" 7 | "math" 8 | ) 9 | 10 | var colors = []color.RGBA{ 11 | {18, 67, 89, 255}, 12 | {58, 165, 229, 255}, 13 | {78, 118, 33, 255}, 14 | {77, 206, 105, 255}, 15 | {104, 6, 9, 255}, 16 | {229, 22, 37, 255}, 17 | {147, 82, 17, 255}, 18 | {225, 205, 31, 255}, 19 | {63, 32, 77, 255}, 20 | {139, 85, 193, 255}, 21 | } 22 | 23 | // DrawPoint draws a point at (`x`; `y`) in the given image with the given color 24 | func DrawPoint(img image.RGBA, x, y, width int, color color.RGBA) { 25 | // Draw multiples layers for the width 26 | for w := 0; w < width; w++ { 27 | r := float64(1+w) 28 | iterations := 2000 29 | t := math.Pi/float64(iterations) 30 | 31 | // Draw the point 32 | for i := 0; i < int(iterations*2); i++ { 33 | // Calculate the coordinates 34 | x1 := r*math.Cos(t)+float64(x) 35 | y1 := r*math.Sin(t)+float64(y) 36 | 37 | // Draw the point 38 | img.Set(int(x1), int(y1), color) 39 | 40 | t += math.Pi/float64(iterations) 41 | } 42 | } 43 | } 44 | 45 | // DrawCircle draws in the given image the middle circle of the visualization with 46 | // the 10 segments in color. 47 | func DrawCircle(img image.RGBA, radius, width, image int) { 48 | fmt.Println("Drawing main circle") 49 | 50 | // Draw multiples layers for the width 51 | for w := 0; w < width; w++ { 52 | iterations := 2000 53 | 54 | // Draw a circle with a parametric equation 55 | t := math.Pi / float64(iterations) 56 | for i := 0; i < iterations*2; i++ { 57 | // Choose a color for each part 58 | var color color.RGBA 59 | for n := range colors { 60 | // Calculate the part of the circle `t` is in 61 | part := t/(math.Pi/5) 62 | color = colors[int(part)%(n+1)] 63 | } 64 | 65 | // Calculate the coordinates for `t` in the center of the image 66 | x := float64(radius + w) * math.Cos(t) + float64(image/2) 67 | y := float64(radius + w) * math.Sin(t) + float64(image/2) 68 | // Draw the point 69 | img.Set(int(x), int(y), color) 70 | 71 | t += math.Pi/float64(iterations) 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /digits/parser.go: -------------------------------------------------------------------------------- 1 | package digits 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | const bubblesBySegment = 15 10 | 11 | // ParseDigits returns a 3D array of integers which represents the segments of the first circle 12 | // then the different lines of a segment and finally the points which represents the decimals. 13 | func ParseDigits(number string) [][][]int { 14 | fmt.Printf("Parsing the digits\n") 15 | 16 | number = strings.Replace(number, ".", "", -1) 17 | 18 | // Generate the 3D array 19 | var digits = make([][][]int, 10) 20 | 21 | // Iterate all the digits of the given number 22 | for digitIndex := 0; digitIndex < len(number)-1; digitIndex++ { 23 | previous, _ := strconv.Atoi(string(number[digitIndex])) 24 | current, _ := strconv.Atoi(string(number[digitIndex+1])) 25 | segments := digits[previous] 26 | 27 | // Create a new segment if no one has been found 28 | if len(segments) == 0 { 29 | segments = append(segments, MakeIntArray(bubblesBySegment)) 30 | } 31 | 32 | // Set the position of the digit in the given number for an array of 10 numbers 33 | position := digitIndex % bubblesBySegment 34 | 35 | // Then generate the segment with the current value and its position 36 | digits[previous] = GenerateSegment(segments, position, current) 37 | } 38 | 39 | return digits 40 | } 41 | 42 | // GenerateSegment returns a segment where the value has been filled 43 | func GenerateSegment(segments [][]int, position, value int) [][]int { 44 | filled := false 45 | // Iterate the segments to find an available position 46 | for i := range segments { 47 | // If the position is free then fill it with the current digit 48 | if segments[i][position] == -1 { 49 | segments[i][position] = value 50 | filled = true 51 | break 52 | } 53 | } 54 | 55 | // If a position has not been found in the existent segments' lines then create one 56 | // and fill it with the current digit 57 | if !filled { 58 | segments = append(segments, MakeIntArray(bubblesBySegment)) 59 | segments[len(segments)-1][position] = value 60 | } 61 | 62 | return segments 63 | } 64 | 65 | // MakeIntArray returns a `size`-elements-array which elements are -1 66 | func MakeIntArray(size int) (array []int) { 67 | array = make([]int, size) 68 | for i := range array { 69 | array[i] = -1 70 | } 71 | 72 | return 73 | } -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "./digits" 5 | digartImage "./image" 6 | "bytes" 7 | "encoding/base64" 8 | "fmt" 9 | "image" 10 | "image/color" 11 | "image/draw" 12 | "image/png" 13 | "syscall/js" 14 | ) 15 | 16 | // CreateImage returns the created image of `width` and `height` dimensions. 17 | func CreateImage(width int, height int, background color.RGBA) *image.RGBA { 18 | rect := image.Rect(0, 0, width, height) 19 | img := image.NewRGBA(rect) 20 | draw.Draw(img, img.Bounds(), &image.Uniform{C: background}, image.ZP, draw.Src) 21 | 22 | return img 23 | } 24 | 25 | func BuildImage(number string) string { 26 | // Read and parse the number 27 | parsedDigits := digits.ParseDigits(number) 28 | 29 | out := bytes.NewBuffer(nil) 30 | 31 | dim := int(float64(len(number))/1.5) 32 | background := color.RGBA{A: 255} 33 | img := CreateImage(dim, dim, background) 34 | 35 | // Draw the elements 36 | digartImage.DrawCircle(*img, 350, 40, dim) 37 | digartImage.DrawData(*img, parsedDigits, 350, dim) 38 | 39 | if err := png.Encode(out, img); err != nil { 40 | panic(err) 41 | } 42 | 43 | b64 := base64.StdEncoding.EncodeToString(out.Bytes()) 44 | return fmt.Sprint(`data:image/png;base64,`, b64) 45 | } 46 | 47 | func main() { 48 | var number string 49 | 50 | c := make(chan struct{}, 0) 51 | 52 | runAction := js.FuncOf(func(this js.Value, args []js.Value) interface{} { 53 | numberInput := js.Global().Get("document"). 54 | Call("getElementById", "number"). 55 | Get("value") 56 | 57 | number = numberInput.String() 58 | 59 | if len(number) < 1500 { 60 | js.Global().Get("document"). 61 | Call("getElementById", "notification-message"). 62 | Set("innerHTML", "The number must contain at least 1500 digits, please.") 63 | 64 | js.Global().Get("document"). 65 | Call("getElementById", "notification-modal"). 66 | Set("className", "modal is-active") 67 | return nil 68 | } 69 | 70 | imageSrc := BuildImage(number) 71 | parameters := map[string]string{ 72 | "src": imageSrc, 73 | "width": "500", 74 | "height": "500", 75 | } 76 | 77 | for id, value := range parameters { 78 | js.Global().Get("document"). 79 | Call("getElementById", "image"). 80 | Set(id, value) 81 | } 82 | 83 | return nil 84 | }) 85 | 86 | js.Global().Get("document"). 87 | Call("getElementById", "submit"). 88 | Call("addEventListener", "click", runAction) 89 | 90 | <-c 91 | } 92 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Digart 5 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 | 33 | 34 | 35 |
36 |
37 |
38 |

39 | circle visualization of a number's digits 40 |

41 |

42 | using Go and WebAssembly 43 |

44 |
45 |
46 |
47 | 48 |
49 | 50 |
51 |
52 |
53 |

54 | 60 |

61 |
62 |
63 |
64 | 65 |
66 |

or

67 |
68 |
69 | 70 |
71 |
72 |
73 |

74 | 80 |

81 | 82 |
83 | 94 |
95 |
96 |
97 |
98 | 99 |
100 |
101 |
102 |

103 | 104 | Read 105 | 106 |

107 | 108 |

109 | 110 | Generate 111 | 112 |

113 |
114 |
115 |
116 |
117 | 118 |
119 |
120 |

The image might take a little time to build up.

121 | 122 |
123 | 124 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /resources/e.txt: -------------------------------------------------------------------------------- 1 | 2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000752044933826560297606737113200709328709127443747047230696977209310141692836819025515108657463772111252389784425056953696770785449969967946864454905987931636889230098793127736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117301238197068416140397019837679320683282376464804295311802328782509819455815301756717361332069811250996181881593041690351598888519345807273866738589422879228499892086805825749279610484198444363463244968487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016768396424378140592714563549061303107208510383750510115747704171898610687396965521267154688957035035402123407849819334321068170121005627880235193033224745015853904730419957777093503660416997329725088687696640355570716226844716256079882651787134195124665201030592123667719432527867539855894489697096409754591856956380236370162112047742722836489613422516445078182442352948636372141740238893441247963574370263755294448337998016125492278509257782562092622648326277933386566481627725164019105900491644998289315056604725802778631864155195653244258698294695930801915298721172556347546396447910145904090586298496791287406870504895858671747985466775757320568128845920541334053922000113786300945560688166740016984205580403363795376452030402432256613527836951177883863874439662532249850654995886234281899707733276171783928034946501434558897071942586398772754710962953741521115136835062752602326484728703920764310059584116612054529703023647254929666938115137322753645098889031360205724817658511806303644281231496550704751025446501172721155519486685080036853228183152196003735625279449515828418829478761085263981395599006737648292244375287184624578036192981971399147564488262603903381441823262515097482798777996437308997038886778227138360577297882412561190717663946507063304527954661855096666185664709711344474016070462621568071748187784437143698821855967095910259686200235371858874856965220005031173439207321139080329363447972735595527734907178379342163701205005451326383544000186323991490705479778056697853358048966906295119432473099587655236812859041383241160722602998330535370876138939639177957454016137223618789365260538155841587186925538606164779834025435128439612946035291332594279490433729908573158029095863138268329147711639633709240031689458636060645845925126994655724839186564209752685082307544254599376917041977780085362730941710163434907696423722294352366125572508814779223151974778060569672538017180776360346245927877846585065605078084421152969752189087401966090665180351650179250461950136658543663271254963990854914420001457476081930221206602433009641270489439039717719518069908699860663658323227870937650226014929101151717763594460202324930028040186772391028809786660565118326004368850881715723866984224220102495055188169480322100251542649463981287367765892768816359831247788652014117411091360116499507662907794364600585194199856016264790761532103872755712699251827568798930276176114616254935649590379804583818232336861201624373656984670378585330527583333793990752166069238053369887956513728559388349989470741618155012539706464817194670834819721448889879067650379590366967249499254527903372963616265897603949857674139735944102374432970935547798262961459144293645142861715858733974679189757121195618738578364475844842355558105002561149239151889309946342841393608038309166281881150371528496705974162562823609216807515017772538740256425347087908913729172282861151591568372524163077225440633787593105982676094420326192428531701878177296023541306067213604600038966109364709514141718577701418060644363681546444005331608778314317444081194942297559931401188868331483280270655383300469329011574414756313999722170380461709289457909627166226074071874997535921275608441473782330327033016823719364800217328573493594756433412994302485023573221459784328264142168487872167336701061509424345698440187331281010794512722373788612605816566805371439612788873252737389039289050686532413806279602593038772769778379286840932536588073398845721874602100531148335132385004782716937621800490479559795929059165547050577751430817511269898518840871856402603530558373783242292418562564425502267215598027401261797192804713960068916382866527700975276706977703643926022437284184088325184877047263844037953016690546593746161932384036389313136432713768884102681121989127522305625675625470172508634976536728860596675274086862740791285657699631378975303466061666980421826772456053066077389962421834085988207186468262321508028828635974683965435885668550377313129658797581050121491620765676995065971534476347032085321560367482860837865680307306265763346977429563464371670939719306087696349532884683361303882943104080029687386911706666614680001512114344225602387447432525076938707777519329994213727721125884360871583483562696166198057252661220679754062106208064988291845439530152998209250300549825704339055357016865312052649561485724925738620691740369521353373253166634546658859728665945113644137033139367211856955395210845840724432383558606310680696492485123263269951460359603729725319836842336390463213671011619282171115028280160448805880238203198149309636959673583274202498824568494127386056649135252670604623445054922758115170931492187959271800194096886698683703730220047531433818109270803001720593553052070070607223399946399057131158709963577735902719628506114651483752620956534671329002599439766311454590268589897911583709341937044115512192011716488056694593813118384376562062784631049034629395002945834116482411496975832601180073169943739350696629571241027323913874175492307186245454322203955273529524024590380574450289224688628533654221381572213116328811205214648980518009202471939171055539011394331668151582884368760696110250517100739276238555338627255353883096067164466237092264680967125406186950214317621166814009759528149390722260111268115310838731761732323526360583817315103459573653822353499293582283685100781088463434998351840445170427018938199424341009057537625776757111809008816418331920196262341628816652137471732547772778348877436651882875215668571950637193656539038944936642176400312152787022236646363575550356557694888654950027085392361710550213114741374410613444554419210133617299628569489919336918472947858072915608851039678195942983318648075608367955149663644896559294818785178403877332624705194505041984774201418394773120281588684570729054405751060128525805659470304683634459265255213700806875200959345360731622611872817392807462309468536782310609792159936001994623799343421068781349734695924646975250624695861690917857397659519939299399556754271465491045686070209901260681870498417807917392407194599632306025470790177452751318680998228473086076653686685551646770291133682756310722334672611370549079536583453863719623585631261838715677411873852772292259474337378569553845624680101390572787101651296663676445187246565373040244368414081448873295784734849000301947788802046032466084287535184836495919508288832320652212810419044804724794929134228495197002260131043006241071797150279343326340799596053144605323048852897291765987601666781193793237245385720960758227717848336161358261289622611812945592746276713779448758675365754486140761193112595851265575973457301533364263076798544338576171533346232527057200530398828949903425956623297578248873502925916682589 -------------------------------------------------------------------------------- /assets/wasm_exec.js: -------------------------------------------------------------------------------- 1 | (()=>{if("undefined"!=typeof global);else if("undefined"!=typeof window)window.global=window;else{if("undefined"==typeof self)throw new Error("cannot export Go (neither global, window nor self is defined)");self.global=self}global.require||"undefined"==typeof require||(global.require=require),!global.fs&&global.require&&(global.fs=require("fs"));const e=()=>{const e=new Error("not implemented");return e.code="ENOSYS",e};if(!global.fs){let t="";global.fs={constants:{O_WRONLY:-1,O_RDWR:-1,O_CREAT:-1,O_TRUNC:-1,O_APPEND:-1,O_EXCL:-1},writeSync(e,i){const n=(t+=s.decode(i)).lastIndexOf("\n");return-1!=n&&(console.log(t.substr(0,n)),t=t.substr(n+1)),i.length},write(t,s,i,n,o,r){if(0!==i||n!==s.length||null!==o)return void r(e());r(null,this.writeSync(t,s))},chmod(t,s,i){i(e())},chown(t,s,i,n){n(e())},close(t,s){s(e())},fchmod(t,s,i){i(e())},fchown(t,s,i,n){n(e())},fstat(t,s){s(e())},fsync(e,t){t(null)},ftruncate(t,s,i){i(e())},lchown(t,s,i,n){n(e())},link(t,s,i){i(e())},lstat(t,s){s(e())},mkdir(t,s,i){i(e())},open(t,s,i,n){n(e())},read(t,s,i,n,o,r){r(e())},readdir(t,s){s(e())},readlink(t,s){s(e())},rename(t,s,i){i(e())},rmdir(t,s){s(e())},stat(t,s){s(e())},symlink(t,s,i){i(e())},truncate(t,s,i){i(e())},unlink(t,s){s(e())},utimes(t,s,i,n){n(e())}}}if(global.process||(global.process={getuid:()=>-1,getgid:()=>-1,geteuid:()=>-1,getegid:()=>-1,getgroups(){throw e()},pid:-1,ppid:-1,umask(){throw e()},cwd(){throw e()},chdir(){throw e()}}),!global.crypto){const e=require("crypto");global.crypto={getRandomValues(t){e.randomFillSync(t)}}}global.performance||(global.performance={now(){const[e,t]=process.hrtime();return 1e3*e+t/1e6}}),global.TextEncoder||(global.TextEncoder=require("util").TextEncoder),global.TextDecoder||(global.TextDecoder=require("util").TextDecoder);const t=new TextEncoder("utf-8"),s=new TextDecoder("utf-8");if(global.Go=class{constructor(){this.argv=["js"],this.env={},this.exit=(e=>{0!==e&&console.warn("exit code:",e)}),this._exitPromise=new Promise(e=>{this._resolveExitPromise=e}),this._pendingEvent=null,this._scheduledTimeouts=new Map,this._nextCallbackTimeoutID=1;const e=(e,t)=>{this.mem.setUint32(e+0,t,!0),this.mem.setUint32(e+4,Math.floor(t/4294967296),!0)},i=e=>{return this.mem.getUint32(e+0,!0)+4294967296*this.mem.getInt32(e+4,!0)},n=e=>{const t=this.mem.getFloat64(e,!0);if(0===t)return;if(!isNaN(t))return t;const s=this.mem.getUint32(e,!0);return this._values[s]},o=(e,t)=>{if("number"==typeof t)return isNaN(t)?(this.mem.setUint32(e+4,2146959360,!0),void this.mem.setUint32(e,0,!0)):0===t?(this.mem.setUint32(e+4,2146959360,!0),void this.mem.setUint32(e,1,!0)):void this.mem.setFloat64(e,t,!0);switch(t){case void 0:return void this.mem.setFloat64(e,0,!0);case null:return this.mem.setUint32(e+4,2146959360,!0),void this.mem.setUint32(e,2,!0);case!0:return this.mem.setUint32(e+4,2146959360,!0),void this.mem.setUint32(e,3,!0);case!1:return this.mem.setUint32(e+4,2146959360,!0),void this.mem.setUint32(e,4,!0)}let s=this._ids.get(t);void 0===s&&(void 0===(s=this._idPool.pop())&&(s=this._values.length),this._values[s]=t,this._goRefCounts[s]=0,this._ids.set(t,s)),this._goRefCounts[s]++;let i=1;switch(typeof t){case"string":i=2;break;case"symbol":i=3;break;case"function":i=4}this.mem.setUint32(e+4,2146959360|i,!0),this.mem.setUint32(e,s,!0)},r=e=>{const t=i(e+0),s=i(e+8);return new Uint8Array(this._inst.exports.mem.buffer,t,s)},l=e=>{const t=i(e+0),s=i(e+8),o=new Array(s);for(let e=0;e{const t=i(e+0),n=i(e+8);return s.decode(new DataView(this._inst.exports.mem.buffer,t,n))},c=Date.now()-performance.now();this.importObject={go:{"runtime.wasmExit":e=>{const t=this.mem.getInt32(e+8,!0);this.exited=!0,delete this._inst,delete this._values,delete this._goRefCounts,delete this._ids,delete this._idPool,this.exit(t)},"runtime.wasmWrite":e=>{const t=i(e+8),s=i(e+16),n=this.mem.getInt32(e+24,!0);fs.writeSync(t,new Uint8Array(this._inst.exports.mem.buffer,s,n))},"runtime.resetMemoryDataView":e=>{this.mem=new DataView(this._inst.exports.mem.buffer)},"runtime.nanotime1":t=>{e(t+8,1e6*(c+performance.now()))},"runtime.walltime1":t=>{const s=(new Date).getTime();e(t+8,s/1e3),this.mem.setInt32(t+16,s%1e3*1e6,!0)},"runtime.scheduleTimeoutEvent":e=>{const t=this._nextCallbackTimeoutID;this._nextCallbackTimeoutID++,this._scheduledTimeouts.set(t,setTimeout(()=>{for(this._resume();this._scheduledTimeouts.has(t);)console.warn("scheduleTimeoutEvent: missed timeout event"),this._resume()},i(e+8)+1)),this.mem.setInt32(e+16,t,!0)},"runtime.clearTimeoutEvent":e=>{const t=this.mem.getInt32(e+8,!0);clearTimeout(this._scheduledTimeouts.get(t)),this._scheduledTimeouts.delete(t)},"runtime.getRandomData":e=>{crypto.getRandomValues(r(e+8))},"syscall/js.finalizeRef":e=>{const t=this.mem.getUint32(e+8,!0);if(this._goRefCounts[t]--,0===this._goRefCounts[t]){const e=this._values[t];this._values[t]=null,this._ids.delete(e),this._idPool.push(t)}},"syscall/js.stringVal":e=>{o(e+24,a(e+8))},"syscall/js.valueGet":e=>{const t=Reflect.get(n(e+8),a(e+16));e=this._inst.exports.getsp(),o(e+32,t)},"syscall/js.valueSet":e=>{Reflect.set(n(e+8),a(e+16),n(e+32))},"syscall/js.valueDelete":e=>{Reflect.deleteProperty(n(e+8),a(e+16))},"syscall/js.valueIndex":e=>{o(e+24,Reflect.get(n(e+8),i(e+16)))},"syscall/js.valueSetIndex":e=>{Reflect.set(n(e+8),i(e+16),n(e+24))},"syscall/js.valueCall":e=>{try{const t=n(e+8),s=Reflect.get(t,a(e+16)),i=l(e+32),r=Reflect.apply(s,t,i);e=this._inst.exports.getsp(),o(e+56,r),this.mem.setUint8(e+64,1)}catch(t){o(e+56,t),this.mem.setUint8(e+64,0)}},"syscall/js.valueInvoke":e=>{try{const t=n(e+8),s=l(e+16),i=Reflect.apply(t,void 0,s);e=this._inst.exports.getsp(),o(e+40,i),this.mem.setUint8(e+48,1)}catch(t){o(e+40,t),this.mem.setUint8(e+48,0)}},"syscall/js.valueNew":e=>{try{const t=n(e+8),s=l(e+16),i=Reflect.construct(t,s);e=this._inst.exports.getsp(),o(e+40,i),this.mem.setUint8(e+48,1)}catch(t){o(e+40,t),this.mem.setUint8(e+48,0)}},"syscall/js.valueLength":t=>{e(t+16,parseInt(n(t+8).length))},"syscall/js.valuePrepareString":s=>{const i=t.encode(String(n(s+8)));o(s+16,i),e(s+24,i.length)},"syscall/js.valueLoadString":e=>{const t=n(e+8);r(e+16).set(t)},"syscall/js.valueInstanceOf":e=>{this.mem.setUint8(e+24,n(e+8)instanceof n(e+16))},"syscall/js.copyBytesToGo":t=>{const s=r(t+8),i=n(t+32);if(!(i instanceof Uint8Array))return void this.mem.setUint8(t+48,0);const o=i.subarray(0,s.length);s.set(o),e(t+40,o.length),this.mem.setUint8(t+48,1)},"syscall/js.copyBytesToJS":t=>{const s=n(t+8),i=r(t+16);if(!(s instanceof Uint8Array))return void this.mem.setUint8(t+48,0);const o=i.subarray(0,s.length);s.set(o),e(t+40,o.length),this.mem.setUint8(t+48,1)},debug:e=>{console.log(e)}}}}async run(e){this._inst=e,this.mem=new DataView(this._inst.exports.mem.buffer),this._values=[NaN,0,null,!0,!1,global,this],this._goRefCounts=[],this._ids=new Map,this._idPool=[],this.exited=!1;let s=4096;const i=e=>{const i=s,n=t.encode(e+"\0");return new Uint8Array(this.mem.buffer,s,n.length).set(n),(s+=n.length)%8!=0&&(s+=8-s%8),i},n=this.argv.length,o=[];this.argv.forEach(e=>{o.push(i(e))}),o.push(0),Object.keys(this.env).sort().forEach(e=>{o.push(i(`${e}=${this.env[e]}`))}),o.push(0);const r=s;o.forEach(e=>{this.mem.setUint32(s,e,!0),this.mem.setUint32(s+4,0,!0),s+=8}),this._inst.exports.run(n,r),this.exited&&this._resolveExitPromise(),await this._exitPromise}_resume(){if(this.exited)throw new Error("Go program has already exited");this._inst.exports.resume(),this.exited&&this._resolveExitPromise()}_makeFuncWrapper(e){const t=this;return function(){const s={id:e,this:this,args:arguments};return t._pendingEvent=s,t._resume(),s.result}}},global.require&&global.require.main===module&&global.process&&global.process.versions&&!global.process.versions.electron){process.argv.length<3&&(console.error("usage: go_js_wasm_exec [wasm binary] [arguments]"),process.exit(1));const e=new Go;e.argv=process.argv.slice(2),e.env=Object.assign({TMPDIR:require("os").tmpdir()},process.env),e.exit=process.exit,WebAssembly.instantiate(fs.readFileSync(process.argv[2]),e.importObject).then(t=>(process.on("exit",t=>{0!==t||e.exited||(e._pendingEvent={id:0},e._resume())}),e.run(t.instance))).catch(e=>{console.error(e),process.exit(1)})}})(); -------------------------------------------------------------------------------- /resources/phi.txt: -------------------------------------------------------------------------------- 1 | 1.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748475408807538689175212663386222353693179318006076672635443338908659593958290563832266131992829026788067520876689250171169620703222104321626954862629631361443814975870122034080588795445474924618569536486444924104432077134494704956584678850987433944221254487706647809158846074998871240076521705751797883416625624940758906970400028121042762177111777805315317141011704666599146697987317613560067087480710131795236894275219484353056783002287856997829778347845878228911097625003026961561700250464338243776486102838312683303724292675263116533924731671112115881863851331620384005222165791286675294654906811317159934323597349498509040947621322298101726107059611645629909816290555208524790352406020172799747175342777592778625619432082750513121815628551222480939471234145170223735805772786160086883829523045926478780178899219902707769038953219681986151437803149974110692608867429622675756052317277752035361393621076738937645560606059216589466759551900400555908950229530942312482355212212415444006470340565734797663972394949946584578873039623090375033993856210242369025138680414577995698122445747178034173126453220416397232134044449487302315417676893752103068737880344170093954409627955898678723209512426893557309704509595684401755519881921802064052905518934947592600734852282101088194644544222318891319294689622002301443770269923007803085261180754519288770502109684249362713592518760777884665836150238913493333122310533923213624319263728910670503399282265263556209029798642472759772565508615487543574826471814145127000602389016207773224499435308899909501680328112194320481964387675863314798571911397815397807476150772211750826945863932045652098969855567814106968372884058746103378105444390943683583581381131168993855576975484149144534150912954070050194775486163075422641729394680367319805861833918328599130396072014455950449779212076124785645916160837059498786006970189409886400764436170933417270919143365013715766011480381430626238051432117348151005590134561011800790506381421527093085880928757034505078081454588199063361298279814117453392731208092897279222132980642946878242748740174505540677875708323731097591511776297844328474790817651809778726841611763250386121129143683437670235037111633072586988325871033632223810980901211019899176841491751233134015273384383723450093478604979294599158220125810459823092552872124137043614910205471855496118087642657651106054588147560443178479858453973128630162544876114852021706440411166076695059775783257039511087823082710647893902111569103927683845386333321565829659773103436032322545743637204124406408882673758433953679593123221343732099574988946995656473600729599983912881031974263125179714143201231127955189477817269141589117799195648125580018455065632952859859100090862180297756378925999164994642819302229355234667475932695165421402109136301819472270789012208728736170734864999815625547281137347987165695274890081443840532748378137824669174442296349147081570073525457070897726754693438226195468615331209533579238014609273510210119190218360675097308957528957746814229543394385493155339630380729169175846101460995055064803679304147236572039860073550760902317312501613204843583648177048481810991602442523271672190189334596378608787528701739359303013359011237102391712659047026349402830766876743638651327106280323174069317334482343564531850581353108549733350759966778712449058363675413289086240632456395357212524261170278028656043234942837301725574405837278267996031739364013287627701243679831144643694767053127249241047167001382478312865650649343418039004101780533950587724586655755229391582397084177298337282311525692609299594224000056062667867435792397245408481765197343626526894488855272027477874733598353672776140759171205132693448375299164998093602461784426757277679001919190703805220461232482391326104327191684512306023627893545432461769975753689041763650254785138246314658336383376023577899267298863216185839590363998183845827644912459809370430555596137973432613483049494968681089535696348281781288625364608420339465381944194571426668237183949183237090857485026656803989744066210536030640026081711266599541993687316094572288810920778822772036366844815325617284117690979266665522384688311371852991921631905201568631222820715599876468423552059285371757807656050367731309751912239738872246825805715974457404842987807352215984266766257807706201943040054255015831250301753409411719101929890384472503329880245014367968441694795954530459103138116218704567997866366174605957000344597011352518134600656553520347888117414994127482641521355677639403907103870881823380680335003804680017480822059109684420264464021877053401003180288166441530913939481564031928227854824145105031888251899700748622879421558957428202166570621880905780880503246769912972872103870736974064356674589202586565739785608595665341070359978320446336346485489497663885351045527298242290699848853696828046459745762651434359050938321243743333870516657149005907105670248879858043718151261004403814880407252440616429022478227152724112085065788838712493635106806365166743222327767755797399270376231914704732395512060705503992088442603708790843334261838413597078164829553714321961189503797714630007555975379570355227144931913217255644012830918050450089921870512118606933573153895935079030073672702331416532042340155374144268715405511647961143323024854404094069114561398730260395182816803448252543267385759005604320245372719291248645813334416985299391357478698957986439498023047116967157362283912018127312916589952759919220318372356827279385637331265479985912463275030060592567454979435088119295056854932593553187291418011364121874707526281068698301357605247194455932195535961045283031488391176930119658583431442489489856558425083410942950277197583352244291257364938075417113739243760143506829878493271299751228688196049835775158771780410697131966753477194792263651901633977128473907933611119140899830560336106098717178305543540356089529290818464143713929437813560482038947912574507707557510300242072662900180904229342494259060666141332287226980690145994511995478016399151412612525728280664331261657469388195106442167387180001100421848302580916543383749236411838885646851431500637319042951481469424314608952547072037405566913069220990804819452975110650464281054177552590951871318883591476599604131796020941530858553323877253802327276329773721431279682167162344211832018028814127474431688472184593927814354740999990722332030592629766112383279833169882539312620065037028844782866694044730794710476125586583752986236250999823233597155072338383324408152577819336426263043302658958170800451278873115935587747217256494700051636672577153920984095032745112153687300912199629522765913163709396860727134269262315475330437993316581107369643142171979434056391551210810813626268885697480680601169189417502722987415869917914534994624441940121978586013736608286907223651477139126874209665137875620591854328888341742920901563133283193575622089713765630978501563154982456445865424792935722828750608481453351352181729587932991171003247622205219464510536245051298843087134443950724426735146286179918323364598369637632722575691597239543830520866474742381511079273494836952396479268993698324917999502789500060459661313463363024949951480805329017902975182515875049007435187983511836032722772601717404535571658855578297291061958193517105548257930709100576358699019297217995168731175563144485648100220014254540554292734588371160209947945720823780436871894480563689182580244499631878342027491015335791072733625328906933474123802222011626277119308544850295419132004009998655666517756640953656197897818380451030356510131589458902871861086905893947136801484570018366495647203294334374298946427412551435905843484091954870152361403173913903616440198455051049121169792001201999605069949664030350863692903941007019450532016234872763232732449439630480890554251379723314751852070910250636859816795304818100739424531700238804759834323450414258431406361272109602282423378228090279765960777108493915174887316877713522390091171173509186006546200990249758527792542781659703834950580106261553336910937846597710529750223173074121778344189411845965861029801877874274456386696612772450384586052641510304089825777754474115332076407588167751497553804711629667771005876646159549677692705496239398570925507027406997814084312496536307186653371806058742242598165307052573834541577054292162998114917508611311765773172095615656478695474489271320608063545779462414531066983742113798168963823533304477883169339728728918103664083269856988254438516675862289930696434684897514840879039647604203610206021717394470263487633654393195229077383616738981178124248365578105034169451563626043003665743108476654877780128577923645418522447236171374229255841593135612866371670328072171553392646325730673063910854108868085742838588280602303341408550390973538726134511962926415995212789311354431460152730902553827104325966226743903745563612286139078319433570590038148700898661315398195857442330441970856696722293142730741384882788975588860799738704470203166834856941990965480298249319817657926829855629723010682777235162740783807431877827318211919695280051608791572128826337968231272562870001500182929757729993579094919640763442861575713544427898383040454702710194580042582021202344580630345033658147218549203679989972935353919681213319516537974539911149424445183033858841290401817818821376006659284941367754317451605409387110368715211640405821934471204482775960541694864539878326269548013915019038995931306703186616706637196402569286713887146631189192685682691995276457997718278759460961617218868109454651578869122410609814197268619255478789926315359472922825080542516906814010781796021885330762305563816316401922454503257656739259976517530801427160714308718862859836037465057134204670083432754230277047793311183666903232885306873879907135900740304907459889513647687608678443238248218930617570319563803230819719363567274196438726258706154330729637038127515170406005057594882723856345156390526577104264594760405569509598408889037620799566388017861855915944111725092313279771138032943765475090165169496509916073833937715833230245701948347400070437618671998483401631826008462619656284649118225688857521346375490254180833821383522245258726789379505375915603579454698509102256225455003017571049469833483545323835260787092219304581782306012370753280678368541306584636788866433486249368010198782799630670259543265137806007386392908564830874157618741897345848450141889765293411013722158643559915527113623322003526677859159890231446163321026519665907632061524383747619049531582968836265042094840105654589130629827717249809641959472340465110419821347689354018038256954956286039244264159867485982280060353862839166201252826607493306196584965199979419393226017235710733642537083033011433624985753635970424446475998999950855041354977558585934576590926533307252775416758431466936767806170350120038448748838233760344077515947781221883070900087386627362091660799050226989270321899760379509890591085910392967345614610700304581921273892599269610621167643642438350141020408632149917815297968152237983224273753657008553469979655413859050326836160222788475547062698439108852103020768604706804556846560491686498860616222952323907098092629302337956482179981632645827888877674520846371971063478923106675469355047615197781699025881840407927510901824482787052505976983753514306224450902202382439823125505841623207188319300693606464682096595006549290109716186526367216107417136183776673327975626854801245657682790317603946555394523143387567730349791578588591011663748455675847952713918608782540104233329857442747118969610485126401975043599092076621558998660736837623188358845081292950114665354828171448464056865246540907815471619625784469575262569455165601519164029217988548909373280314651922247590030965715490505361043776868772619159528449204647868973473708598413845131621192972012634240773694545981865029659233534512568454974541129819735876670728601616056204230636066130281496773445797737750557564665475256322648177116997857087122831543104569123262503497681152452174497396136748822046480519688754341969511933120450216051429384844754523821270143830957855813619678302310685080845876952059053294683384904712099162556365034003439670828933698367423001575117385151269123066172276414421607512917341874714315093241924914160969998672815823859257359823894849274919646152272273338746312138436262116379467062032630225055489580573083750461299231136299173069489407342588319483999274163950984439634057635284717562762192786522539608720131080486406534396168875452534263098969517619019770963192258709342165955974471750157538376741522280570650280683143356524917199733358403064153550759115974264366482846628136802174505909705894602744292632222215459450758046571206068639904308236939693208237490767561190171561305424813311715242568478463363770015204417916501168232575236160495749706390822443444510351219048819830276001766809850965245439007199098034993026860675523879685292194732393352370086650221407464554037222343481675749373144640928379006539196774010355861936181566836616864892395554961452826472894994160615803045867891461971728155451100056660542499691974102798740593276434953714525167694620698597880946950174730228414275718871940921209137994059430370504364838600434645227993302923901865922689874992113256560557840142335426058951056203690720289393159204404768359276364799600596404860761989159298194950878786027663459905404263770045900803279434720629825445256356479542992488198646136171314485773469953475577155491384239289401754034139973846169481293479242234609743019627523013828607224496380953838401526567819764507588547855155492345234781646033062938842009950803260140918302574385770671025227243666905988908545015570754230316665924723528924702588624794887546252765727285151112878270673454310244515233456542284311039679528296250193698939983473961763988095735415260145372964681473821843600521099472119416591494716705203792255209633645848468041447780302164728623999264048363508773747824501638200895240322534379925790129265640155537754091751704419627285039126695956664877242967660367303453668734049079141886945214715827908157233969124039985869390855173079801955546128513408912061084012213617070570430060569246855916468834773320856891412679428448041384682813256929148160109786272696866867373917118931462269134894580427789899608144709524762905019260311649206867743318661546966896601822663578788750608856243562678932797354633904182108774638039216244772025672699596391824687788455497179038515839204748319903127622437066235092518775434140107112335865907748122063763459019884225472727655290504399502524440391136582670813300580588209460310208261341369127572936992893029961730892843670315238589753987388936807441526373794240506448764171768613552343269865728970463069180174277972173889859443284852057257588337563820150546720651674252681894851673328046307647813293132602893229366045210213189812987661526244487486693890406178469916665417485084597970146178215845014919572109825089234517474512254327386819725864944588083771398685065984085457731654169174067052111949166286337732263753475666370022120327524389997736006074042702972203634778048298834855189525079474605519940340110771169725644261005092059843362535847069597185762616776630211747878341975644501838041029203240408826617344339090263522350506828582854432839618480925376130820115626869907999117084755586982150310073563240421988569584200682439926953784403202222374628147659230605547476936830576549677690471159625502474507809624837449908025613750915622359081010534493941774294277091445166668700415228544638076615351141556487854936011387473103828773313388391709646174829063156788065182761765798535021665998607464012674884121130098549938337106031962506702797524310119377335548537011694674858888363080333287739571656275340367272180705622562326374148833499289970258977299224036941750743427314194157432466794578586039894075097356363688815672159676354380665593938934382075984061216064317664421902677773799145579945031468708716266226524133590569928494006372744908821635242948022566330458553636337251762049074624062938962390622030424872688432377631733574205753997574373508409657792180880089420590662572782307692788656445563758012667280952527379828030076636976928164844651277473822397061738567507146692748220374881122563994075227626464994658463674019559973702838393119884822335539964978333165008467491254522956512409390963784095416901234675375280139080830863022653352387069273071984654649454979101134287154636695543437462154391886526085366974366530588562164411648068912837357794341530609478457270987037976921346205969538843826760827659181773627669918727803754219954172428335791064520613736884708545165822193158645377018313401818827251099922917614711860529176551422881123566217241692680620648845317615164272953585798375412375876100415475805595730122459276711895277333823356043374201321392804317053379463646428351993014576706491847707768959885421647973371769625943938648074893633201098893643528324494132569317438323509258286421276209473432879984387198291625035886368 -------------------------------------------------------------------------------- /resources/pi.txt: -------------------------------------------------------------------------------- 1 | 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601015033086179286809208747609178249385890097149096759852613655497818931297848216829989487226588048575640142704775551323796414515237462343645428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435064302184531910484810053706146806749192781911979399520614196634287544406437451237181921799983910159195618146751426912397489409071864942319615679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539057962685610055081066587969981635747363840525714591028970641401109712062804390397595156771577004203378699360072305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398315019701651511685171437657618351556508849099898599823873455283316355076479185358932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233260972997120844335732654893823911932597463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100449293215160842444859637669838952286847831235526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396665573092547110557853763466820653109896526918620564769312570586356620185581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830634328587856983052358089330657574067954571637752542021149557615814002501262285941302164715509792592309907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571853061422881375850430633217518297986622371721591607716692547487389866549494501146540628433663937900397692656721463853067360965712091807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513622224771589150495309844489333096340878076932599397805419341447377441842631298608099888687413260472156951623965864573021631598193195167353812974167729478672422924654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001593776471651228935786015881617557829735233446042815126272037343146531977774160319906655418763979293344195215413418994854447345673831624993419131814809277771038638773431772075456545322077709212019051660962804909263601975988281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267945612753181340783303362542327839449753824372058353114771199260638133467768796959703098339130771098704085913374641442822772634659470474587847787201927715280731767907707157213444730605700733492436931138350493163128404251219256517980694113528013147013047816437885185290928545201165839341965621349143415956258658655705526904965209858033850722426482939728584783163057777560688876446248246857926039535277348030480290058760758251047470916439613626760449256274204208320856611906254543372131535958450687724602901618766795240616342522577195429162991930645537799140373404328752628889639958794757291746426357455254079091451357111369410911939325191076020825202618798531887705842972591677813149699009019211697173727847684726860849003377024242916513005005168323364350389517029893922334517220138128069650117844087451960121228599371623130171144484640903890644954440061986907548516026327505298349187407866808818338510228334508504860825039302133219715518430635455007668282949304137765527939751754613953984683393638304746119966538581538420568533862186725233402830871123282789212507712629463229563989898935821167456270102183564622013496715188190973038119800497340723961036854066431939509790190699639552453005450580685501956730229219139339185680344903982059551002263535361920419947455385938102343955449597783779023742161727111723643435439478221818528624085140066604433258885698670543154706965747458550332323342107301545940516553790686627333799585115625784322988273723198987571415957811196358330059408730681216028764962867446047746491599505497374256269010490377819868359381465741268049256487985561453723478673303904688383436346553794986419270563872931748723320837601123029911367938627089438799362016295154133714248928307220126901475466847653576164773794675200490757155527819653621323926406160136358155907422020203187277605277219005561484255518792530343513984425322341576233610642506390497500865627109535919465897514131034822769306247435363256916078154781811528436679570611086153315044521274739245449454236828860613408414863776700961207151249140430272538607648236341433462351897576645216413767969031495019108575984423919862916421939949072362346468441173940326591840443780513338945257423995082965912285085558215725031071257012668302402929525220118726767562204154205161841634847565169998116141010029960783869092916030288400269104140792886215078424516709087000699282120660418371806535567252532567532861291042487761825829765157959847035622262934860034158722980534989650226291748788202734209222245339856264766914905562842503912757710284027998066365825488926488025456610172967026640765590429099456815065265305371829412703369313785178609040708667114965583434347693385781711386455873678123014587687126603489139095620099393610310291616152881384379099042317473363948045759314931405297634757481193567091101377517210080315590248530906692037671922033229094334676851422144773793937517034436619910403375111735471918550464490263655128162288244625759163330391072253837421821408835086573917715096828874782656995995744906617583441375223970968340800535598491754173818839994469748676265516582765848358845314277568790029095170283529716344562129640435231176006651012412006597558512761785838292041974844236080071930457618932349229279650198751872127267507981255470958904556357921221033346697499235630254947802490114195212382815309114079073860251522742995818072471625916685451333123948049470791191532673430282441860414263639548000448002670496248201792896476697583183271314251702969234889627668440323260927524960357996469256504936818360900323809293459588970695365349406034021665443755890045632882250545255640564482465151875471196218443965825337543885690941130315095261793780029741207665147939425902989695946995565761218656196733786236256125216320862869222103274889218654364802296780705765615144632046927906821207388377814233562823608963208068222468012248261177185896381409183903673672220888321513755600372798394004152970028783076670944474560134556417254370906979396122571429894671543578468788614445812314593571984922528471605049221242470141214780573455105008019086996033027634787081081754501193071412233908663938339529425786905076431006383519834389341596131854347546495569781038293097164651438407007073604112373599843452251610507027056235266012764848308407611830130527932054274628654036036745328651057065874882256981579367897669742205750596834408697350201410206723585020072452256326513410559240190274216248439140359989535394590944070469120914093870012645600162374288021092764579310657922955249887275846101264836999892256959688159205600101655256375678566722796619885782794848855834397518744545512965634434803966420557982936804352202770984294232533022576341807039476994159791594530069752148293366555661567873640053666564165473217043903521329543529169414599041608753201868379370234888689479151071637852902345292440773659495630510074210871426134974595615138498713757047101787957310422969066670214498637464595280824369445789772330048764765241339075920434019634039114732023380715095222010682563427471646024335440051521266932493419673977041595683753555166730273900749729736354964533288869844061196496162773449518273695588220757355176651589855190986665393549481068873206859907540792342402300925900701731960362254756478940647548346647760411463233905651343306844953979070903023460461470961696886885014083470405460742958699138296682468185710318879065287036650832431974404771855678934823089431068287027228097362480939962706074726455399253994428081137369433887294063079261595995462624629707062594845569034711972996409089418059534393251236235508134949004364278527138315912568989295196427287573946914272534366941532361004537304881985517065941217352462589548730167600298865925786628561249665523533829428785425340483083307016537228563559152534784459818313411290019992059813522051173365856407826484942764411376393866924803118364453698589175442647399882284621844900877769776312795722672655562596282542765318300134070922334365779160128093179401718598599933849235495640057099558561134980252499066984233017350358044081168552653117099570899427328709258487894436460050410892266917835258707859512983441729535195378855345737426085902908176515578039059464087350612322611200937310804854852635722825768203416050484662775045003126200800799804925485346941469775164932709504934639382432227188515974054702148289711177792376122578873477188196825462981268685817050740272550263329044976277894423621674119186269439650671515779586756482399391760426017633870454990176143641204692182370764887834196896861181558158736062938603810171215855272668300823834046564758804051380801633638874216371406435495561868964112282140753302655100424104896783528588290243670904887118190909494533144218287661810310073547705498159680772009474696134360928614849417850171807793068108546900094458995279424398139213505586422196483491512639012803832001097738680662877923971801461343244572640097374257007359210031541508936793008169980536520276007277496745840028362405346037263416554259027601834840306811381855105979705664007509426087885735796037324514146786703688098806097164258497595138069309449401515422221943291302173912538355915031003330325111749156969174502714943315155885403922164097229101129035521815762823283182342548326111912800928252561902052630163911477247331485739107775874425387611746578671169414776421441111263583553871361011023267987756410246824032264834641766369806637857681349204530224081972785647198396308781543221166912246415911776732253264335686146186545222681268872684459684424161078540167681420808850280054143613146230821025941737562389942075713627516745731891894562835257044133543758575342698699472547031656613991999682628247270641336222178923903176085428943733935618891651250424404008952719837873864805847268954624388234375178852014395600571048119498842390606136957342315590796703461491434478863604103182350736502778590897578272731305048893989009923913503373250855982655867089242612429473670193907727130706869170926462548423240748550366080136046689511840093668609546325002145852930950000907151058236267293264537382104938724996699339424685516483261134146110680267446637334375340764294026682973865220935701626384648528514903629320199199688285171839536691345222444708045923966028171565515656661113598231122506289058549145097157553900243931535190902107119457300243880176615035270862602537881797519478061013715004489917210022201335013106016391541589578037117792775225978742891917915522417189585361680594741234193398420218745649256443462392531953135103311476394911995072858430658361935369329699289837914941939406085724863968836903265564364216644257607914710869984315733749648835292769328220762947282381537409961545598798259891093717126218283025848112389011968221429457667580718653806506487026133892822994972574530332838963818439447707794022843598834100358385423897354243956475556840952248445541392394100016207693636846776413017819659379971557468541946334893748439129742391433659360410035234377706588867781139498616478747140793263858738624732889645643598774667638479466504074111825658378878454858148962961273998413442726086061872455452360643153710112746809778704464094758280348769758948328241239292960582948619196670918958089833201210318430340128495116203534280144127617285830243559830032042024512072872535581195840149180969253395075778400067465526031446167050827682772223534191102634163157147406123850425845988419907611287258059113935689601431668283176323567325417073420817332230462987992804908514094790368878687894930546955703072619009502076433493359106024545086453628935456862958531315337183868265617862273637169757741830239860065914816164049449650117321313895747062088474802365371031150898427992754426853277974311395143574172219759799359685252285745263796289612691572357986620573408375766873884266405990993505000813375432454635967504844235284874701443545419576258473564216198134073468541117668831186544893776979566517279662326714810338643913751865946730024434500544995399742372328712494834706044063471606325830649829795510109541836235030309453097335834462839476304775645015008507578949548931393944899216125525597701436858943585877526379625597081677643800125436502371412783467926101995585224717220177723700417808419423948725406801556035998390548985723546745642390585850216719031395262944554391316631345308939062046784387785054239390524731362012947691874975191011472315289326772533918146607300089027768963114810902209724520759167297007850580717186381054967973100167870850694207092232908070383263453452038027860990556900134137182368370991949516489600755049341267876436746384902063964019766685592335654639138363185745698147196210841080961884605456039038455343729141446513474940784884423772175154334260306698831768331001133108690421939031080143784334151370924353013677631084913516156422698475074303297167469640666531527035325467112667522460551199581831963763707617991919203579582007595605302346267757943936307463056901080114942714100939136913810725813781357894005599500183542511841721360557275221035268037357265279224173736057511278872181908449006178013889710770822931002797665935838758909395688148560263224393726562472776037890814458837855019702843779362407825052704875816470324581290878395232453237896029841669225489649715606981192186584926770403956481278102179913217416305810554598801300484562997651121241536374515005635070127815926714241342103301566165356024733807843028655257222753049998837015348793008062601809623815161366903341111386538510919367393835229345888322550887064507539473952043968079067086806445096986548801682874343786126453815834280753061845485903798217994599681154419742536344399602902510015888272164745006820704193761584547123183460072629339550548239557137256840232268213012476794522644820910235647752723082081063518899152692889108455571126603965034397896278250016110153235160519655904211844949907789992007329476905868577878720982901352956613978884860509786085957017731298155314951681467176959760994210036183559138777817698458758104466283998806006162298486169353373865787735983361613384133853684211978938900185295691967804554482858483701170967212535338758621582310133103877668272115726949518179589754693992642197915523385766231676275475703546994148929041301863861194391962838870543677743224276809132365449485366768000001065262485473055861598999140170769838548318875014293890899506854530765116803337322265175662207526951791442252808165171667766727930354851542040238174608923283917032754257508676551178593950027933895920576682789677644531840404185540104351348389531201326378369283580827193783126549617459970567450718332065034556644034490453627560011250184335607361222765949278393706478426456763388188075656121689605041611390390639601620221536849410926053876887148379895599991120991646464411918568277004574243434021672276445589330127781586869525069499364610175685060167145354315814801054588605645501332037586454858403240298717093480910556211671546848477803944756979804263180991756422809873998766973237695737015808068229045992123661689025962730430679316531149401764737693873514093361833216142802149763399189835484875625298752423873077559555955465196394401821840998412489826236737714672260616336432964063357281070788758164043814850188411431885988276944901193212968271588841338694346828590066640806314077757725705630729400492940302420498416565479736705485580445865720227637840466823379852827105784319753541795011347273625774080213476826045022851579795797647467022840999561601569108903845824502679265942055503958792298185264800706837650418365620945554346135134152570065974881916341359556719649654032187271602648593049039787489589066127250794828276938953521753621850796297785146188432719223223810158744450528665238022532843891375273845892384422535472653098171578447834215822327020690287232330053862163479885094695472004795231120150432932266282727632177908840087861480221475376578105819702226309717495072127248479478169572961423658595782090830733233560348465318730293026659645013718375428897557971449924654038681799213893469244741985097334626793321072686870768062639919361965044099542167627840914669856925715074315740793805323925239477557441591845821562518192155233709607483329234921034514626437449805596103307994145347784574699992128599999399612281615219314888769388022281083001986016549416542616968586788372609587745676182507275992950893180521872924610867639958916145855058397274209809097817293239301067663868240401113040247007350857828724627134946368531815469690466968693925472519413992914652423857762550047485295476814795467007050347999588867695016124972282040303995463278830695976249361510102436555352230690612949388599015734661023712235478911292547696176005047974928060721268039226911027772261025441492215765045081206771735712027180242968106203776578837166909109418074487814049075517820385653909910477594141321543284406250301802757169650820964273484146957263978842560084531214065935809041271135920041975985136254796160632288736181367373244506079244117639975974619383584574915988097667447093006546342423460634237474666080431701260052055928493695941434081468529815053947178900451835755154125223590590687264878635752541911288877371766374860276606349603536794702692322971868327717393236192007774522126247518698334951510198642698878471719396649769070825217423365662725928440620430214113719922785269984698847702323823840055655517889087661360130477098438611687052310553149162517283732728676007248172987637569816335415074608838663640693470437206688651275688266149730788657015685016918647488541679154596507234287730699853713904300266530783987763850323818215535597323530686043010675760838908627049841888595138091030423595782495143988590113185835840667472370297149785084145853085781339156270760356390763947311455495832266945702494139831634332378975955680856836297253867913275055542524491943589128405045226953812179131914513500993846311774017971512283785460116035955402864405902496466930707769055481028850208085800878115773817191741776017330738554758006056014337743299012728677253043182519757916792969965041460706645712588834697979642931622965520168797300035646304579308840327480771811555330909887025505207680463034608658165394876951960044084820659673794731680864156456505300498816164905788311543454850526600698230931577765003780704661264706021457505793270962047825615247145918965223608396645624105195510522357239739512881816405978591427914816542632892004281609136937773722299983327082082969955737727375667615527113922588055201898876201141680054687365580633471603734291703907986396522961312801782679717289822936070288069087768660593252746378405397691848082041021944719713869256084162451123980620113184541244782050110798760717155683154078865439041210873032402010685341947230476666721749869868547076781205124736792479193150856444775379853799732234456122785843296846647513336573692387201464723679427870042503255589926884349592876124007558756946413705625140011797133166207153715436006876477318675587148783989081074295309410605969443158477539700943988394914432353668539209946879645066533985738887866147629443414010498889931600512076781035886116602029611936396821349607501116498327856353161451684576956871090029997698412632665023477167286573785790857466460772283415403114415294188047825438761770790430001566986776795760909966936075594965152736349811896413043311662774712338817406037317439705406703109676765748695358789670031925866259410510533584384656023391796749267844763708474978333655579007384191473198862713525954625181604342253729962863267496824058060296421146386436864224724887283434170441573482481833301640566959668866769563491416328426414974533349999480002669987588815935073578151958899005395120853510357261373640343675347141048360175464883004078464167452167371904831096767113443494819262681110739948250607394950735031690197318521195526356325843390998224986240670310768318446607291248747540316179699411397387765899868554170318847788675929026070043212666179192235209382278788809886335991160819235355570464634911320859189796132791319756490976000139962344455350143464268604644958624769094347048293294140411146540923988344435159133201077394411184074107684981066347241048239358274019449356651610884631256785297769734684303061462418035852933159734583038455410337010916767763742762102137013548544509263071901147318485749233181672072137279355679528443925481560913728128406333039373562420016045664557414588166052166608738748047243391212955877763906969037078828527753894052460758496231574369171131761347838827194168606625721036851321566478001476752310393578606896111259960281839309548709059073861351914591819510297327875571049729011487171897180046961697770017913919613791417162707018958469214343696762927459109940060084983568425201915593703701011049747339493877885989417433031785348707603221982970579751191440510994235883034546353492349826883624043327267415540301619505680654180939409982020609994140216890900708213307230896621197755306659188141191577836272927461561857103721724710095214236964830864102592887457999322374955191221951903424452307535133806856807354464995127203174487195403976107308060269906258076020292731455252078079914184290638844373499681458273372072663917670201183004648190002413083508846584152148991276106513741539435657211390328574918769094413702090517031487773461652879848235338297260136110984514841823808120540996125274580881099486972216128524897425555516076371675054896173016809613803811914361143992106380050832140987604599309324851025168294467260666138151745712559754953580239983146982203613380828499356705575524712902745397762140493182014658008021566536067765508783804304134310591804606800834591136640834887408005741272586704792258319127415739080914383138456424150940849133918096840251163991936853225557338966953749026620923261318855891580832455571948453875628786128859004106006073746501402627824027346962528217174941582331749239683530136178653673760642166778137739951006589528877427662636841830680190804609849809469763667335662282915132352788806157768278159588669180238940333076441912403412022316368577860357276941541778826435238131905028087018575047046312933353757285386605888904583111450773942935201994321971171642235005644042979892081594307167019857469273848653833436145794634175922573898588001698014757420542995801242958105456510831046297282937584161162532562516572498078492099897990620035936509934721582965174135798491047111660791587436986541222348341887722929446335178653856731962559852026072947674072616767145573649812105677716893484917660771705277187601199908144113058645577910525684304811440261938402322470939249802933550731845890355397133088446174107959162511714864874468611247605428673436709046678468670274091881014249711149657817724279347070216688295610877794405048437528443375108828264771978540006509704033021862556147332117771174413350281608840351781452541964320309576018694649088681545285621346988355444560249556668436602922195124830910605377201980218310103270417838665447181260397190688462370857518080035327047185659499476124248110999288679158969049563947624608424065930948621507690314987020673533848349550836366017848771060809804269247132410009464014373603265645184566792456669551001502298330798496079949882497061723674493612262229617908143114146609412341593593095854079139087208322733549572080757165171876599449856937956238755516175754380917805280294642004472153962807463602113294255916002570735628126387331060058910652457080244749375431841494014821199962764531068006631183823761639663180931444671298615527598201451410275600689297502463040173514891945763607893528555053173314164570504996443890936308438744847839616840518452732884032345202470568516465716477139323775517294795126132398229602394548579754586517458787713318138752959809412174227300352296508089177705068259248822322154938048371454781647213976820963320508305647920482085920475499857320388876391601995240918938945576768749730856955958010659526503036266159750662225084067428898265907510637563569968211510949669744580547288693631020367823250182323708459790111548472087618212477813266330412076216587312970811230758159821248639807212407868878114501655825136178903070860870198975889807456643955157415363193191981070575336633738038272152798849350397480015890519420879711308051233933221903466249917169150948541401871060354603794643379005890957721180804465743962806186717861017156740967662080295766577051291209907944304632892947306159510430902221439371849560634056189342513057268291465783293340524635028929175470872564842600349629611654138230077313327298305001602567240141851520418907011542885799208121984493156999059182011819733500126187728036812481995877070207532406361259313438595542547781961142935163561223496661522614735399674051584998603552953329245752388810136202347624669055816438967863097627365504724348643071218494373485300606387644566272186661701238127715621379746149861328744117714552444708997144522885662942440230184791205478498574521634696448973892062401943518310088283480249249085403077863875165911302873958787098100772718271874529013972836614842142871705531796543076504534324600536361472618180969976933486264077435199928686323835088756683595097265574815431940195576850437248001020413749831872259677387154958399718444907279141965845930083942637020875635398216962055324803212267498911402678528599673405242031091797899905718821949391320753431707980023736590985375520238911643467185582906853711897952626234492483392496342449714656846591248918556629589329909035239233333647435203707701010843880032907598342170185542283861617210417603011645918780539367447472059985023582891833692922337323999480437108419659473162654825748099482509991833006976569367159689364493348864744213500840700660883597235039532340179582557036016936990988671132109798897070517280755855191269930673099250704070245568507786790694766126298082251633136399521170984528092630375922426742575599892892783704744452189363203489415521044597261883800300677617931381399162058062701651024458869247649246891924612125310275731390840470007143561362316992371694848132554200914530410371354532966206392105479824392125172540132314902740585892063217589494345489068463993137570910346332714153162232805522972979538018801628590735729554162788676498274186164218789885741071649069191851162815285486794173638906653885764229158342500673612453849160674137340173572779956341043326883569507814931378007362354180070619180267328551191942676091221035987469241172837493126163395001239599240508454375698507957046222664619000103500490183034153545842833764378111988556318777792537201166718539541835984438305203762819440761594106820716970302285152250573126093046898423433152732131361216582808075212631547730604423774753505952287174402666389148817173086436111389069420279088143119448799417154042103412190847094080254023932942945493878640230512927119097513536000921971105412096683111516328705423028470073120658032626417116165957613272351566662536672718998534199895236884830999302757419916463841427077988708874229277053891227172486322028898425125287217826030500994510824783572905691988555467886079462805371227042466543192145281760741482403827835829719301017888345674167811398954750448339314689630763396657226727043393216745421824557062524797219978668542798977992339579057581890622525473582205236424850783407110144980478726691990186438822932305382318559732869780922253529591017341407334884761005564018242392192695062083183814546983923664613639891012102177095976704908305081854704194664371312299692358895384930136356576186106062228705599423371631021278457446463989738188566746260879482018647487672727222062676465338099801966883680994159075776852639865146253336312450536402610569605513183813174261184420189088853196356986962795036738424313011331753305329802016688817481342988681585577810343231753 --------------------------------------------------------------------------------