namespace: change -> git.grassecon.net/kamikazechaser/vise
This commit is contained in:
parent
194522fd95
commit
d8ef336919
@ -156,7 +156,7 @@ Multipage outputs, like listings, are handled using the _sink_ output constraint
|
|||||||
|
|
||||||
### Languages support
|
### Languages support
|
||||||
|
|
||||||
**Not yet implemeennted**
|
**Not yet implemented**
|
||||||
|
|
||||||
Language for rendering is determined at the top-level state.
|
Language for rendering is determined at the top-level state.
|
||||||
|
|
||||||
|
@ -13,10 +13,9 @@ import (
|
|||||||
"github.com/alecthomas/participle/v2"
|
"github.com/alecthomas/participle/v2"
|
||||||
"github.com/alecthomas/participle/v2/lexer"
|
"github.com/alecthomas/participle/v2/lexer"
|
||||||
|
|
||||||
"git.defalsify.org/vise/vm"
|
"git.grassecon.net/kamikazechaser/vise/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// Asm assembles bytecode from the vise assembly mini-language.
|
// Asm assembles bytecode from the vise assembly mini-language.
|
||||||
type Asm struct {
|
type Asm struct {
|
||||||
Instructions []*Instruction `@@*`
|
Instructions []*Instruction `@@*`
|
||||||
@ -373,9 +372,7 @@ func Parse(s string, w io.Writer) (int, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
batch := Batcher{
|
batch := Batcher{}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var rn int
|
var rn int
|
||||||
for _, v := range ast.Instructions {
|
for _, v := range ast.Instructions {
|
||||||
|
@ -7,10 +7,9 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise/vm"
|
"git.grassecon.net/kamikazechaser/vise/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func TestParserInit(t *testing.T) {
|
func TestParserInit(t *testing.T) {
|
||||||
var b []byte
|
var b []byte
|
||||||
b = vm.NewLine(b, vm.HALT, nil, nil, nil)
|
b = vm.NewLine(b, vm.HALT, nil, nil, nil)
|
||||||
|
@ -3,7 +3,7 @@ package asm
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.defalsify.org/vise/vm"
|
"git.grassecon.net/kamikazechaser/vise/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BatchCode defines quasi-opcodes that expand to mulitple individual vm instructions.
|
// BatchCode defines quasi-opcodes that expand to mulitple individual vm instructions.
|
||||||
|
@ -3,10 +3,9 @@ package asm
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise/vm"
|
"git.grassecon.net/kamikazechaser/vise/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func TestMenuInterpreter(t *testing.T) {
|
func TestMenuInterpreter(t *testing.T) {
|
||||||
m := NewMenuProcessor()
|
m := NewMenuProcessor()
|
||||||
err := m.Add("DOWN", "0", "inky", "foo")
|
err := m.Add("DOWN", "0", "inky", "foo")
|
||||||
|
@ -6,11 +6,11 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.defalsify.org/vise/asm"
|
"git.grassecon.net/kamikazechaser/vise/asm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if (len(os.Args) < 2) {
|
if len(os.Args) < 2 {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
fp := os.Args[1]
|
fp := os.Args[1]
|
||||||
|
@ -2,14 +2,14 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
|
||||||
"git.defalsify.org/vise/vm"
|
"git.grassecon.net/kamikazechaser/vise/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if (len(os.Args) < 2) {
|
if len(os.Args) < 2 {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
fp := os.Args[1]
|
fp := os.Args[1]
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.defalsify.org/vise/testdata"
|
"git.grassecon.net/kamikazechaser/vise/testdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.defalsify.org/vise/engine"
|
"git.grassecon.net/kamikazechaser/vise/engine"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -3,9 +3,9 @@ package engine
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewDefaultEngine is a convenience function to instantiate a filesystem-backed engine with no output constraints.
|
// NewDefaultEngine is a convenience function to instantiate a filesystem-backed engine with no output constraints.
|
||||||
|
@ -6,11 +6,11 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/render"
|
"git.grassecon.net/kamikazechaser/vise/render"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
"git.defalsify.org/vise/vm"
|
"git.grassecon.net/kamikazechaser/vise/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config globally defines behavior of all components driven by the engine.
|
// Config globally defines behavior of all components driven by the engine.
|
||||||
|
@ -8,10 +8,10 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
"git.defalsify.org/vise/testdata"
|
"git.grassecon.net/kamikazechaser/vise/testdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -137,7 +137,6 @@ func TestEngineExecInvalidInput(t *testing.T) {
|
|||||||
rs := NewFsWrapper(dataDir, &st)
|
rs := NewFsWrapper(dataDir, &st)
|
||||||
ca := cache.NewCache().WithCacheSize(1024)
|
ca := cache.NewCache().WithCacheSize(1024)
|
||||||
|
|
||||||
|
|
||||||
en := NewEngine(Config{
|
en := NewEngine(Config{
|
||||||
Root: "root",
|
Root: "root",
|
||||||
}, &st, &rs, ca, ctx)
|
}, &st, &rs, ca, ctx)
|
||||||
|
@ -8,9 +8,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLoopTop(t *testing.T) {
|
func TestLoopTop(t *testing.T) {
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"git.defalsify.org/vise/persist"
|
"git.grassecon.net/kamikazechaser/vise/persist"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunPersisted performs a single vm execution from client input using a persisted state.
|
// RunPersisted performs a single vm execution from client input using a persisted state.
|
||||||
|
@ -6,9 +6,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/persist"
|
"git.grassecon.net/kamikazechaser/vise/persist"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPersist(t *testing.T) {
|
func TestPersist(t *testing.T) {
|
||||||
|
@ -11,10 +11,10 @@ import (
|
|||||||
|
|
||||||
testdataloader "github.com/peteole/testdata-loader"
|
testdataloader "github.com/peteole/testdata-loader"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/engine"
|
"git.grassecon.net/kamikazechaser/vise/engine"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -11,10 +11,10 @@ import (
|
|||||||
|
|
||||||
testdataloader "github.com/peteole/testdata-loader"
|
testdataloader "github.com/peteole/testdata-loader"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/engine"
|
"git.grassecon.net/kamikazechaser/vise/engine"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -9,10 +9,10 @@ import (
|
|||||||
|
|
||||||
testdataloader "github.com/peteole/testdata-loader"
|
testdataloader "github.com/peteole/testdata-loader"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/engine"
|
"git.grassecon.net/kamikazechaser/vise/engine"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
2
go.mod
2
go.mod
@ -1,4 +1,4 @@
|
|||||||
module git.defalsify.org/vise
|
module git.grassecon.net/kamikazechaser/vise
|
||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
|
@ -5,10 +5,11 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/fxamacker/cbor/v2"
|
"github.com/fxamacker/cbor/v2"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FsPersister is an implementation of Persister that saves state to the file system.
|
// FsPersister is an implementation of Persister that saves state to the file system.
|
||||||
|
@ -7,9 +7,9 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
"git.defalsify.org/vise/vm"
|
"git.grassecon.net/kamikazechaser/vise/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSerializeState(t *testing.T) {
|
func TestSerializeState(t *testing.T) {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package persist
|
package persist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Persister interface defines the methods needed for a component that can store the execution state to a storage location.
|
// Persister interface defines the methods needed for a component that can store the execution state to a storage location.
|
||||||
@ -14,4 +14,3 @@ type Persister interface {
|
|||||||
GetState() *state.State // Get the currently loaded State object.
|
GetState() *state.State // Get the currently loaded State object.
|
||||||
GetMemory() cache.Memory // Get the currently loaded Cache object.
|
GetMemory() cache.Memory // Get the currently loaded Cache object.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Page exectues output rendering into pages constrained by size.
|
// Page exectues output rendering into pages constrained by size.
|
||||||
@ -151,7 +151,6 @@ func(pg *Page) RenderTemplate(sym string, values map[string]string, idx uint16)
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
b := bytes.NewBuffer([]byte{})
|
b := bytes.NewBuffer([]byte{})
|
||||||
err = tp.Execute(b, values)
|
err = tp.Execute(b, values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -332,4 +331,3 @@ func(pg *Page) render(sym string, values map[string]string, idx uint16) (string,
|
|||||||
}
|
}
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,9 @@ package render
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func TestPageCurrentSize(t *testing.T) {
|
func TestPageCurrentSize(t *testing.T) {
|
||||||
t.Skip("usage is not in use, and it is unclear how it should be calculated")
|
t.Skip("usage is not in use, and it is unclear how it should be calculated")
|
||||||
ca := cache.NewCache()
|
ca := cache.NewCache()
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestSizeResource struct {
|
type TestSizeResource struct {
|
||||||
@ -172,7 +172,6 @@ lala poo
|
|||||||
1:foo the foo
|
1:foo the foo
|
||||||
2:go to bar`
|
2:go to bar`
|
||||||
|
|
||||||
|
|
||||||
if r != expect {
|
if r != expect {
|
||||||
t.Fatalf("expected:\n\t%x\ngot:\n\t%x\n", expect, r)
|
t.Fatalf("expected:\n\t%x\ngot:\n\t%x\n", expect, r)
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package resource
|
package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StateResource struct {
|
type StateResource struct {
|
||||||
|
@ -3,7 +3,7 @@ package resource
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestStateResourceInit(t *testing.T) {
|
func TestStateResourceInit(t *testing.T) {
|
||||||
|
3
testdata/testdata.go
vendored
3
testdata/testdata.go
vendored
@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
testdataloader "github.com/peteole/testdata-loader"
|
testdataloader "github.com/peteole/testdata-loader"
|
||||||
|
|
||||||
"git.defalsify.org/vise/vm"
|
"git.grassecon.net/kamikazechaser/vise/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type genFunc func() error
|
type genFunc func() error
|
||||||
@ -177,7 +177,6 @@ func Generate() (string, error) {
|
|||||||
return dir, err
|
return dir, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Generate outputs bytecode, templates and content symbols to a specified directory.
|
// Generate outputs bytecode, templates and content symbols to a specified directory.
|
||||||
//
|
//
|
||||||
// The directory must exist, and must not have been used already in the same code execution.
|
// The directory must exist, and must not have been used already in the same code execution.
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -16,7 +16,6 @@ var (
|
|||||||
ctrlRegex = regexp.MustCompile(ctrlRegexStr)
|
ctrlRegex = regexp.MustCompile(ctrlRegexStr)
|
||||||
symRegexStr = "^[a-zA-Z0-9][a-zA-Z0-9_]+$"
|
symRegexStr = "^[a-zA-Z0-9][a-zA-Z0-9_]+$"
|
||||||
symRegex = regexp.MustCompile(symRegexStr)
|
symRegex = regexp.MustCompile(symRegexStr)
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckInput validates the given byte string as client input.
|
// CheckInput validates the given byte string as client input.
|
||||||
|
@ -5,10 +5,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/render"
|
"git.grassecon.net/kamikazechaser/vise/render"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Vm holds sub-components mutated by the vm execution.
|
// Vm holds sub-components mutated by the vm execution.
|
||||||
@ -167,7 +167,6 @@ func(vm *Vm) RunDeadCheck(b []byte, ctx context.Context) ([]byte, error) {
|
|||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
log.Printf("no code remaining but not terminating")
|
log.Printf("no code remaining but not terminating")
|
||||||
location, _ := vm.st.Where()
|
location, _ := vm.st.Where()
|
||||||
if location == "" {
|
if location == "" {
|
||||||
|
@ -7,10 +7,10 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise/cache"
|
"git.grassecon.net/kamikazechaser/vise/cache"
|
||||||
"git.defalsify.org/vise/render"
|
"git.grassecon.net/kamikazechaser/vise/render"
|
||||||
"git.defalsify.org/vise/resource"
|
"git.grassecon.net/kamikazechaser/vise/resource"
|
||||||
"git.defalsify.org/vise/state"
|
"git.grassecon.net/kamikazechaser/vise/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
var dynVal = "three"
|
var dynVal = "three"
|
||||||
@ -456,7 +456,6 @@ func TestRunReturn(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestRunLoadInput(t *testing.T) {
|
func TestRunLoadInput(t *testing.T) {
|
||||||
st := state.NewState(5)
|
st := state.NewState(5)
|
||||||
rs := TestResource{}
|
rs := TestResource{}
|
||||||
|
Loading…
Reference in New Issue
Block a user