func (c *Checker) processCgoExported(pkg *lint.Pkg, node ast.Node) {
	if node, ok := node.(*ast.FuncDecl); ok {
		if node.Doc == nil {
			return
		}
		for _, cmt := range node.Doc.List {
			if !strings.HasPrefix(cmt.Text, "//go:cgo_export_") {
				return
			}
			obj := pkg.TypesInfo.ObjectOf(node.Name)
			c.graph.roots = append(c.graph.roots, c.graph.getNode(obj))
		}
	}
}

func ( c * Checker ) processCgoExported ( pkg * lint . Pkg , node ast . Node ) { if node , ok := node . ( * ast . FuncDecl ) ; ok { if node . Doc == nil { return } for _ , cmt := range node . Doc . List { if ! strings . HasPrefix ( cmt . Text , " " ) { return } obj := pkg . TypesInfo . ObjectOf ( node . Name ) c . graph . roots = append ( c . graph . roots , c . graph . getNode ( obj ) ) } } }

// processCgoExported marks functions as used if they're being
// exported to cgo.

processCgoExported marks functions as used if they re being exported to cgo .


func WritePackage(buf *bytes.Buffer, p *Package) {
	fmt.Fprintf(buf, "%s:\n", p)

	var names []string
	maxname := 0
	for name := range p.Members {
		if l := len(name); l > maxname {
			maxname = l
		}
		names = append(names, name)
	}

	from := p.Pkg
	sort.Strings(names)
	for _, name := range names {
		switch mem := p.Members[name].(type) {
		case *NamedConst:
			fmt.Fprintf(buf, "  const %-*s %s = %s\n",
				maxname, name, mem.Name(), mem.Value.RelString(from))

		case *Function:
			fmt.Fprintf(buf, "  func  %-*s %s\n",
				maxname, name, relType(mem.Type(), from))

		case *Type:
			fmt.Fprintf(buf, "  type  %-*s %s\n",
				maxname, name, relType(mem.Type().Underlying(), from))
			for _, meth := range typeutil.IntuitiveMethodSet(mem.Type(), &p.Prog.MethodSets) {
				fmt.Fprintf(buf, "    %s\n", types.SelectionString(meth, types.RelativeTo(from)))
			}

		case *Global:
			fmt.Fprintf(buf, "  var   %-*s %s\n",
				maxname, name, relType(mem.Type().(*types.Pointer).Elem(), from))
		}
	}

	fmt.Fprintf(buf, "\n")
}

func WritePackage ( buf * bytes . Buffer , p * Package ) { fmt . Fprintf ( buf , " \n " , p ) var names [ ] string maxname := 0 for name := range p . Members { if l := len ( name ) ; l > maxname { maxname = l } names = append ( names , name ) } from := p . Pkg sort . Strings ( names ) for _ , name := range names { switch mem := p . Members [ name ] . ( type ) { case * NamedConst : fmt . Fprintf ( buf , " \n " , maxname , name , mem . Name ( ) , mem . Value . RelString ( from ) ) case * Function : fmt . Fprintf ( buf , " \n " , maxname , name , relType ( mem . Type ( ) , from ) ) case * Type : fmt . Fprintf ( buf , " \n " , maxname , name , relType ( mem . Type ( ) . Underlying ( ) , from ) ) for _ , meth := range typeutil . IntuitiveMethodSet ( mem . Type ( ) , & p . Prog . MethodSets ) { fmt . Fprintf ( buf , " \n " , types . SelectionString ( meth , types . RelativeTo ( from ) ) ) } case * Global : fmt . Fprintf ( buf , " \n " , maxname , name , relType ( mem . Type ( ) . ( * types . Pointer ) . Elem ( ) , from ) ) } } fmt . Fprintf ( buf , " \n " ) }

// WritePackage writes to buf a human-readable summary of p.

WritePackage writes to buf a human - readable summary of p .


func NewLinter(name string, config LinterConfig) (*Linter, error) {
	if p, ok := predefinedPatterns[config.Pattern]; ok {
		config.Pattern = p
	}
	regex, err := regexp.Compile("(?m:" + config.Pattern + ")")
	if err != nil {
		return nil, err
	}
	if config.PartitionStrategy == nil {
		config.PartitionStrategy = partitionPathsAsDirectories
	}
	return &Linter{
		LinterConfig: config,
		Name:         name,
		regex:        regex,
	}, nil
}

func NewLinter ( name string , config LinterConfig ) ( * Linter , error ) { if p , ok := predefinedPatterns [ config . Pattern ] ; ok { config . Pattern = p } regex , err := regexp . Compile ( " " + config . Pattern + " " ) if err != nil { return nil , err } if config . PartitionStrategy == nil { config . PartitionStrategy = partitionPathsAsDirectories } return & Linter { LinterConfig : config , Name : name , regex : regex , } , nil }

// NewLinter returns a new linter from a config


func (d *Descriptions) IsStub(fn *ssa.Function) bool {
	if len(fn.Blocks) == 0 {
		return true
	}
	if len(fn.Blocks) > 1 {
		return false
	}
	instrs := lintdsl.FilterDebug(fn.Blocks[0].Instrs)
	if len(instrs) != 1 {
		return false
	}

	switch instrs[0].(type) {
	case *ssa.Return:
		// Since this is the only instruction, the return value must
		// be a constant. We consider all constants as stubs, not just
		// the zero value. This does not, unfortunately, cover zero
		// initialised structs, as these cause additional
		// instructions.
		return true
	case *ssa.Panic:
		return true
	default:
		return false
	}
}

// IsStub reports whether a function is a stub. A function is
// considered a stub if it has no instructions or exactly one
// instruction, which must be either returning only constant values or
// a panic.

IsStub reports whether a function is a stub . A function is considered a stub if it has no instructions or exactly one instruction which must be either returning only constant values or a panic .


func (c *Checker) CheckUnexportedReturn(j *lint.Job) {
	for _, fn := range j.Program.InitialFunctions {
		if fn.Synthetic != "" || fn.Parent() != nil {
			continue
		}
		if !ast.IsExported(fn.Name()) || IsInMain(j, fn) || IsInTest(j, fn) {
			continue
		}
		sig := fn.Type().(*types.Signature)
		if sig.Recv() != nil && !ast.IsExported(Dereference(sig.Recv().Type()).(*types.Named).Obj().Name()) {
			continue
		}
		res := sig.Results()
		for i := 0; i < res.Len(); i++ {
			if named, ok := DereferenceR(res.At(i).Type()).(*types.Named); ok &&
				!ast.IsExported(named.Obj().Name()) &&
				named != types.Universe.Lookup("error").Type() {
				j.Errorf(fn, "should not return unexported type")
			}
		}
	}
}

func ( c * Checker ) CheckUnexportedReturn ( j * lint . Job ) { for _ , fn := range j . Program . InitialFunctions { if fn . Synthetic != " " || fn . Parent ( ) != nil { continue } if ! ast . IsExported ( fn . Name ( ) ) || IsInMain ( j , fn ) || IsInTest ( j , fn ) { continue } sig := fn . Type ( ) . ( * types . Signature ) if sig . Recv ( ) != nil && ! ast . IsExported ( Dereference ( sig . Recv ( ) . Type ( ) ) . ( * types . Named ) . Obj ( ) . Name ( ) ) { continue } res := sig . Results ( ) for i := 0 ; i < res . Len ( ) ; i ++ { if named , ok := DereferenceR ( res . At ( i ) . Type ( ) ) . ( * types . Named ) ; ok && ! ast . IsExported ( named . Obj ( ) . Name ( ) ) && named != types . Universe . Lookup ( " " ) . Type ( ) { j . Errorf ( fn , " " ) } } } }

// CheckUnexportedReturn checks that exported functions on exported
// types do not return unexported types.

CheckUnexportedReturn checks that exported functions on exported types do not return unexported types .


func CreateProgram(lprog *loader.Program, mode ssa.BuilderMode) *ssa.Program {
	prog := ssa.NewProgram(lprog.Fset, mode)

	for _, info := range lprog.AllPackages {
		if info.TransitivelyErrorFree {
			prog.CreatePackage(info.Pkg, info.Files, &info.Info, info.Importable)
		}
	}

	return prog
}

func CreateProgram ( lprog * loader . Program , mode ssa . BuilderMode ) * ssa . Program { prog := ssa . NewProgram ( lprog . Fset , mode ) for _ , info := range lprog . AllPackages { if info . TransitivelyErrorFree { prog . CreatePackage ( info . Pkg , info . Files , & info . Info , info . Importable ) } } return prog }

// CreateProgram returns a new program in SSA form, given a program
// loaded from source.  An SSA package is created for each transitively
// error-free package of lprog.
//
// Code for bodies of functions is not built until Build is called
// on the result.
//
// mode controls diagnostics and checking during SSA construction.
//

CreateProgram returns a new program in SSA form given a program loaded from source . An SSA package is created for each transitively error - free package of lprog . Code for bodies of functions is not built until Build is called on the result . mode controls diagnostics and checking during SSA construction .


func (d *directiveParser) IsIgnored(issue *Issue) bool {
	d.lock.Lock()
	path := issue.Path.Relative()
	ranges, ok := d.files[path]
	if !ok {
		ranges = d.parseFile(path)
		sort.Sort(ranges)
		d.files[path] = ranges
	}
	d.lock.Unlock()
	for _, r := range ranges {
		if r.matches(issue) {
			debug("nolint: matched %s to issue %s", r, issue)
			r.matched = true
			return true
		}
	}
	return false
}

func ( d * directiveParser ) IsIgnored ( issue * Issue ) bool { d . lock . Lock ( ) path := issue . Path . Relative ( ) ranges , ok := d . files [ path ] if ! ok { ranges = d . parseFile ( path ) sort . Sort ( ranges ) d . files [ path ] = ranges } d . lock . Unlock ( ) for _ , r := range ranges { if r . matches ( issue ) { debug ( " " , r , issue ) r . matched = true return true } } return false }

// IsIgnored returns true if the given linter issue is ignored by a linter directive.

IsIgnored returns true if the given linter issue is ignored by a linter directive .


func (d *directiveParser) Unmatched() map[string]ignoredRanges {
	unmatched := map[string]ignoredRanges{}
	for path, ranges := range d.files {
		for _, ignore := range ranges {
			if !ignore.matched {
				unmatched[path] = append(unmatched[path], ignore)
			}
		}
	}
	return unmatched
}

func ( d * directiveParser ) Unmatched ( ) map [ string ] ignoredRanges { unmatched := map [ string ] ignoredRanges { } for path , ranges := range d . files { for _ , ignore := range ranges { if ! ignore . matched { unmatched [ path ] = append ( unmatched [ path ] , ignore ) } } } return unmatched }

// Unmatched returns all the ranges which were never used to ignore an issue


func (d *directiveParser) LoadFiles(paths []string) error {
	d.lock.Lock()
	defer d.lock.Unlock()
	filenames, err := pathsToFileGlobs(paths)
	if err != nil {
		return err
	}
	for _, filename := range filenames {
		ranges := d.parseFile(filename)
		sort.Sort(ranges)
		d.files[filename] = ranges
	}
	return nil
}

func ( d * directiveParser ) LoadFiles ( paths [ ] string ) error { d . lock . Lock ( ) defer d . lock . Unlock ( ) filenames , err := pathsToFileGlobs ( paths ) if err != nil { return err } for _ , filename := range filenames { ranges := d . parseFile ( filename ) sort . Sort ( ranges ) d . files [ filename ] = ranges } return nil }


func ForArch(arch string) *Sizes {
	wordSize := int64(8)
	maxAlign := int64(8)
	switch build.Default.GOARCH {
	case "386", "arm":
		wordSize, maxAlign = 4, 4
	case "amd64p32":
		wordSize = 4
	}
	return &Sizes{WordSize: wordSize, MaxAlign: maxAlign}
}

func ForArch ( arch string ) * Sizes { wordSize := int64 ( 8 ) maxAlign := int64 ( 8 ) switch build . Default . GOARCH { case " " , " " : wordSize , maxAlign = 4 , 4 case " " : wordSize = 4 } return & Sizes { WordSize : wordSize , MaxAlign : maxAlign } }

// ForArch returns a correct Sizes for the given architecture.

ForArch returns a correct Sizes for the given architecture .


func ConvertedFrom(v Value, typ string) bool {
	change, ok := v.Value.(*ssa.ChangeType)
	return ok && IsType(change.X.Type(), typ)
}

func ConvertedFrom ( v Value , typ string ) bool { change , ok := v . Value . ( * ssa . ChangeType ) return ok && IsType ( change . X . Type ( ) , typ ) }

// ConvertedFrom reports whether value v was converted from type typ.

ConvertedFrom reports whether value v was converted from type typ .


func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
	root bool, sequence bool, mapping bool, simple_key bool) bool {

	emitter.root_context = root
	emitter.sequence_context = sequence
	emitter.mapping_context = mapping
	emitter.simple_key_context = simple_key

	switch event.typ {
	case yaml_ALIAS_EVENT:
		return yaml_emitter_emit_alias(emitter, event)
	case yaml_SCALAR_EVENT:
		return yaml_emitter_emit_scalar(emitter, event)
	case yaml_SEQUENCE_START_EVENT:
		return yaml_emitter_emit_sequence_start(emitter, event)
	case yaml_MAPPING_START_EVENT:
		return yaml_emitter_emit_mapping_start(emitter, event)
	default:
		return yaml_emitter_set_emitter_error(emitter,
			fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
	}
}

func yaml_emitter_emit_node ( emitter * yaml_emitter_t , event * yaml_event_t , root bool , sequence bool , mapping bool , simple_key bool ) bool { emitter . root_context = root emitter . sequence_context = sequence emitter . mapping_context = mapping emitter . simple_key_context = simple_key switch event . typ { case yaml_ALIAS_EVENT : return yaml_emitter_emit_alias ( emitter , event ) case yaml_SCALAR_EVENT : return yaml_emitter_emit_scalar ( emitter , event ) case yaml_SEQUENCE_START_EVENT : return yaml_emitter_emit_sequence_start ( emitter , event ) case yaml_MAPPING_START_EVENT : return yaml_emitter_emit_mapping_start ( emitter , event ) default : return yaml_emitter_set_emitter_error ( emitter , fmt . Sprintf ( " " , event . typ ) ) } }


func IsBlank(id ast.Expr) bool {
	ident, _ := id.(*ast.Ident)
	return ident != nil && ident.Name == "_"
}

func IsBlank ( id ast . Expr ) bool { ident , _ := id . ( * ast . Ident ) return ident != nil && ident . Name == " " }

// isBlank returns whether id is the blank identifier "_".
// If id == nil, the answer is false.

isBlank returns whether id is the blank identifier _ . If id == nil the answer is false .


func Dereference(T types.Type) types.Type {
	if p, ok := T.Underlying().(*types.Pointer); ok {
		return p.Elem()
	}
	return T
}

func Dereference ( T types . Type ) types . Type { if p , ok := T . Underlying ( ) . ( * types . Pointer ) ; ok { return p . Elem ( ) } return T }

// Dereference returns a pointer's element type; otherwise it returns
// T.

Dereference returns a pointer s element type ; otherwise it returns T .


func TCPDialCheck(addr string, timeout time.Duration) Check {
	return func() error {
		conn, err := net.DialTimeout("tcp", addr, timeout)
		if err != nil {
			return err
		}
		return conn.Close()
	}
}

func TCPDialCheck ( addr string , timeout time . Duration ) Check { return func ( ) error { conn , err := net . DialTimeout ( " " , addr , timeout ) if err != nil { return err } return conn . Close ( ) } }

// TCPDialCheck returns a Check that checks TCP connectivity to the provided
// endpoint.

TCPDialCheck returns a Check that checks TCP connectivity to the provided endpoint .


func HTTPGetCheck(url string, timeout time.Duration) Check {
	client := http.Client{
		Timeout: timeout,
		// never follow redirects
		CheckRedirect: func(*http.Request, []*http.Request) error {
			return http.ErrUseLastResponse
		},
	}
	return func() error {
		resp, err := client.Get(url)
		if err != nil {
			return err
		}
		resp.Body.Close()
		if resp.StatusCode != 200 {
			return fmt.Errorf("returned status %d", resp.StatusCode)
		}
		return nil
	}
}

func
HTTPGetCheck
(
url
string
,
timeout
time
.
Duration
)
Check
{
client
:=
http
.
Client
{
Timeout
:
timeout
,
// never follow redirects
CheckRedirect
:
func
(
*
http
.
Request
,
[
]
*
http
.
Request
)
error
{
return
http
.
ErrUseLastResponse
}
,
}
return
func
(
)
error
{
resp
,
err
:=
client
.
Get
(
url
)
if
err
!=
{
return
err
}
resp
.
Body
.
Close
(
)
if
resp
.
StatusCode
!=
200
{
return
fmt
.
Errorf
(
"
"
,
resp
.
StatusCode
)
}
return
}
}

// HTTPGetCheck returns a Check that performs an HTTP GET request against the
// specified URL. The check fails if the response times out or returns a non-200
// status code.

HTTPGetCheck returns a Check that performs an HTTP GET request against the specified URL . The check fails if the response times out or returns a non - 200 status code .


func DNSResolveCheck(host string, timeout time.Duration) Check {
	resolver := net.Resolver{}
	return func() error {
		ctx, cancel := context.WithTimeout(context.Background(), timeout)
		defer cancel()
		addrs, err := resolver.LookupHost(ctx, host)
		if err != nil {
			return err
		}
		if len(addrs) < 1 {
			return fmt.Errorf("could not resolve host")
		}
		return nil
	}
}

func DNSResolveCheck ( host string , timeout time . Duration ) Check { resolver := net . Resolver { } return func ( ) error { ctx , cancel := context . WithTimeout ( context . Background ( ) , timeout ) defer cancel ( ) addrs , err := resolver . LookupHost ( ctx , host ) if err != nil { return err } if len ( addrs ) < 1 { return fmt . Errorf ( " " ) } return nil } }

// DNSResolveCheck returns a Check that makes sure the provided host can resolve
// to at least one IP address within the specified timeout.

DNSResolveCheck returns a Check that makes sure the provided host can resolve to at least one IP address within the specified timeout .


func NewHandler() Handler {
	h := &basicHandler{
		livenessChecks:  make(map[string]Check),
		readinessChecks: make(map[string]Check),
	}
	h.Handle("/live", http.HandlerFunc(h.LiveEndpoint))
	h.Handle("/ready", http.HandlerFunc(h.ReadyEndpoint))
	return h
}

func NewHandler ( ) Handler { h := & basicHandler { livenessChecks : make ( map [ string ] Check ) , readinessChecks : make ( map [ string ] Check ) , } h . Handle ( " " , http . HandlerFunc ( h . LiveEndpoint ) ) h . Handle ( " " , http . HandlerFunc ( h . ReadyEndpoint ) ) return h }

// NewHandler creates a new basic Handler


func NewMetricsHandler(registry prometheus.Registerer, namespace string) Handler {
	return &metricsHandler{
		handler:   NewHandler(),
		registry:  registry,
		namespace: namespace,
	}
}

func NewMetricsHandler ( registry prometheus . Registerer , namespace string ) Handler { return & metricsHandler { handler : NewHandler ( ) , registry : registry , namespace : namespace , } }

// NewMetricsHandler returns a healthcheck Handler that also exposes metrics
// into the provided Prometheus registry.

NewMetricsHandler returns a healthcheck Handler that also exposes metrics into the provided Prometheus registry .


func Timeout(check Check, timeout time.Duration) Check {
	return func() error {
		c := make(chan error, 1)
		go func() { c <- check() }()
		select {
		case err := <-c:
			return err
		case <-time.After(timeout):
			return timeoutError(timeout)
		}
	}
}

func Timeout ( check Check , timeout time . Duration ) Check { return func ( ) error { c := make ( chan error , 1 ) go func ( ) { c <- check ( ) } ( ) select { case err := <- c : return err case <- time . After ( timeout ) : return timeoutError ( timeout ) } } }

// Timeout adds a timeout to a Check. If the underlying check takes longer than
// the timeout, it returns an error.

Timeout adds a timeout to a Check . If the underlying check takes longer than the timeout it returns an error .


func NewPinger() *Pinger {
	rand.Seed(time.Now().UnixNano())
	return &Pinger{
		id:      rand.Intn(0xffff),
		seq:     rand.Intn(0xffff),
		addrs:   make(map[string]*net.IPAddr),
		network: "ip",
		source:  "",
		source6: "",
		hasIPv4: false,
		hasIPv6: false,
		Size:    TimeSliceLength,
		MaxRTT:  time.Second,
		OnRecv:  nil,
		OnIdle:  nil,
		Debug:   false,
	}
}

func NewPinger ( ) * Pinger { rand . Seed ( time . Now ( ) . UnixNano ( ) ) return & Pinger { id : rand . Intn ( 0xffff ) , seq : rand . Intn ( 0xffff ) , addrs : make ( map [ string ] * net . IPAddr ) , network : " " , source : " " , source6 : " " , hasIPv4 : false , hasIPv6 : false , Size : TimeSliceLength , MaxRTT : time . Second , OnRecv : nil , OnIdle : nil , Debug : false , } }

// NewPinger returns a new Pinger struct pointer


func (p *Pinger) Network(network string) (string, error) {
	origNet := p.network
	switch network {
	case "ip":
		fallthrough
	case "udp":
		p.network = network
	default:
		return origNet, errors.New(network + " can't be used as ICMP endpoint")
	}
	return origNet, nil
}

func ( p * Pinger ) Network ( network string ) ( string , error ) { origNet := p . network switch network { case " " : fallthrough case " " : p . network = network default : return origNet , errors . New ( network + " " ) } return origNet , nil }

// Network sets a network endpoints for ICMP ping and returns the previous
// setting. network arg should be "ip" or "udp" string or if others are
// specified, it returns an error. If this function isn't called, Pinger
// uses "ip" as default.

Network sets a network endpoints for ICMP ping and returns the previous setting . network arg should be ip or udp string or if others are specified it returns an error . If this function isn t called Pinger uses ip as default .


func (p *Pinger) AddIP(ipaddr string) error {
	addr := net.ParseIP(ipaddr)
	if addr == nil {
		return fmt.Errorf("%s is not a valid textual representation of an IP address", ipaddr)
	}
	p.mu.Lock()
	p.addrs[addr.String()] = &net.IPAddr{IP: addr}
	if isIPv4(addr) {
		p.hasIPv4 = true
	} else if isIPv6(addr) {
		p.hasIPv6 = true
	}
	p.mu.Unlock()
	return nil
}

func ( p * Pinger ) AddIP ( ipaddr string ) error { addr := net . ParseIP ( ipaddr ) if addr == nil { return fmt . Errorf ( " " , ipaddr ) } p . mu . Lock ( ) p . addrs [ addr . String ( ) ] = & net . IPAddr { IP : addr } if isIPv4 ( addr ) { p . hasIPv4 = true } else if isIPv6 ( addr ) { p . hasIPv6 = true } p . mu . Unlock ( ) return nil }

// AddIP adds an IP address to Pinger. ipaddr arg should be a string like
// "192.0.2.1".

AddIP adds an IP address to Pinger . ipaddr arg should be a string like 192 . 0 . 2 . 1 .


func (p *Pinger) AddIPAddr(ip *net.IPAddr) {
	p.mu.Lock()
	p.addrs[ip.String()] = ip
	if isIPv4(ip.IP) {
		p.hasIPv4 = true
	} else if isIPv6(ip.IP) {
		p.hasIPv6 = true
	}
	p.mu.Unlock()
}

func ( p * Pinger ) AddIPAddr ( ip * net . IPAddr ) { p . mu . Lock ( ) p . addrs [ ip . String ( ) ] = ip if isIPv4 ( ip . IP ) { p . hasIPv4 = true } else if isIPv6 ( ip . IP ) { p . hasIPv6 = true } p . mu . Unlock ( ) }

// AddIPAddr adds an IP address to Pinger. ip arg should be a net.IPAddr
// pointer.

AddIPAddr adds an IP address to Pinger . ip arg should be a net . IPAddr pointer .


func (p *Pinger) RemoveIP(ipaddr string) error {
	addr := net.ParseIP(ipaddr)
	if addr == nil {
		return fmt.Errorf("%s is not a valid textual representation of an IP address", ipaddr)
	}
	p.mu.Lock()
	delete(p.addrs, addr.String())
	p.mu.Unlock()
	return nil
}

func ( p * Pinger ) RemoveIP ( ipaddr string ) error { addr := net . ParseIP ( ipaddr ) if addr == nil { return fmt . Errorf ( " " , ipaddr ) } p . mu . Lock ( ) delete ( p . addrs , addr . String ( ) ) p . mu . Unlock ( ) return nil }

// RemoveIP removes an IP address from Pinger. ipaddr arg should be a string
// like "192.0.2.1".

RemoveIP removes an IP address from Pinger . ipaddr arg should be a string like 192 . 0 . 2 . 1 .


func (p *Pinger) RemoveIPAddr(ip *net.IPAddr) {
	p.mu.Lock()
	delete(p.addrs, ip.String())
	p.mu.Unlock()
}

func ( p * Pinger ) RemoveIPAddr ( ip * net . IPAddr ) { p . mu . Lock ( ) delete ( p . addrs , ip . String ( ) ) p . mu . Unlock ( ) }

// RemoveIPAddr removes an IP address from Pinger. ip arg should be a net.IPAddr
// pointer.

RemoveIPAddr removes an IP address from Pinger . ip arg should be a net . IPAddr pointer .


func MakeLang(s string, lang string) (slug string) {
	slug = strings.TrimSpace(s)

	// Custom substitutions
	// Always substitute runes first
	slug = SubstituteRune(slug, CustomRuneSub)
	slug = Substitute(slug, CustomSub)

	// Process string with selected substitution language
	switch lang {
	case "de":
		slug = SubstituteRune(slug, deSub)
	case "en":
		slug = SubstituteRune(slug, enSub)
	case "es":
		slug = SubstituteRune(slug, esSub)
	case "fi":
		slug = SubstituteRune(slug, fiSub)
	case "gr":
		slug = SubstituteRune(slug, grSub)
	case "nl":
		slug = SubstituteRune(slug, nlSub)
	case "pl":
		slug = SubstituteRune(slug, plSub)
	case "tr":
		slug = SubstituteRune(slug, trSub)
	default: // fallback to "en" if lang not found
		slug = SubstituteRune(slug, enSub)
	}

	// Process all non ASCII symbols
	slug = unidecode.Unidecode(slug)

	slug = strings.ToLower(slug)

	// Process all remaining symbols
	slug = regexpNonAuthorizedChars.ReplaceAllString(slug, "-")
	slug = regexpMultipleDashes.ReplaceAllString(slug, "-")
	slug = strings.Trim(slug, "-_")

	if MaxLength > 0 {
		slug = smartTruncate(slug)
	}

	return slug
}

// MakeLang returns slug generated from provided string and will use provided
// language for chars substitution.

MakeLang returns slug generated from provided string and will use provided language for chars substitution .


func Substitute(s string, sub map[string]string) (buf string) {
	buf = s
	var keys []string
	for k := range sub {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, key := range keys {
		buf = strings.Replace(buf, key, sub[key], -1)
	}
	return
}

func Substitute ( s string , sub map [ string ] string ) ( buf string ) { buf = s var keys [ ] string for k := range sub { keys = append ( keys , k ) } sort . Strings ( keys ) for _ , key := range keys { buf = strings . Replace ( buf , key , sub [ key ] , - 1 ) } return }

// Substitute returns string with superseded all substrings from
// provided substitution map. Substitution map will be applied in alphabetic
// order. Many passes, on one substitution another one could apply.

Substitute returns string with superseded all substrings from provided substitution map . Substitution map will be applied in alphabetic order . Many passes on one substitution another one could apply .


func SubstituteRune(s string, sub map[rune]string) string {
	var buf bytes.Buffer
	for _, c := range s {
		if d, ok := sub[c]; ok {
			buf.WriteString(d)
		} else {
			buf.WriteRune(c)
		}
	}
	return buf.String()
}

func SubstituteRune ( s string , sub map [ rune ] string ) string { var buf bytes . Buffer for _ , c := range s { if d , ok := sub [ c ] ; ok { buf . WriteString ( d ) } else { buf . WriteRune ( c ) } } return buf . String ( ) }

// SubstituteRune substitutes string chars with provided rune
// substitution map. One pass.

SubstituteRune substitutes string chars with provided rune substitution map . One pass .


func Parse() error {
	args := os.Args
	if len(args) == 1 {
		return nil
	}

	// Global flags.
	fset := flag.CommandLine
	fset.Usage = Usage
	out := fsetOutput(fset)

	if err := fset.Parse(args[1:]); err != nil {
		return err
	}

	// Handle version request.
	if f := fset.Lookup(VersionBoolFlag); f != nil {
		if v, ok := f.Value.(flag.Getter); ok {
			// All values implemented by the flag package implement the flag.Getter interface.
			if b, ok := v.Get().(bool); ok && b {
				// The flag was defined as a bool and is set.
				program := programName(args[0])
				fmt.Fprintf(out, "%s version %s %s/%s\n",
					program, buildinfo(),
					runtime.GOOS, runtime.GOARCH)
				return nil
			}
		}
	}

	// No cmdflag.
	if fset.NArg() == 0 {
		return nil
	}

	// Subcommand.
	idx := len(args) - fset.NArg()
	s := args[idx]
	args = args[idx+1:]
	for _, sub := range subs {
		if sub.name != s {
			continue
		}

		fs, handler := sub.init(out)
		if err := fs.Parse(args); err != nil {
			return err
		}
		return handler(args[len(args)-fs.NArg():]...)
	}

	return fmt.Errorf("%s is not a valid cmdflag", s)
}

// Parse parses the command line arguments including the global flags and, if any, the cmdflag and its flags.
//
// If the VersionBoolFlag is defined as a global boolean flag, then the program version is displayed and the program stops.

Parse parses the command line arguments including the global flags and if any the cmdflag and its flags . If the VersionBoolFlag is defined as a global boolean flag then the program version is displayed and the program stops .


func (xxh XXHZero) Sum(b []byte) []byte {
	h32 := xxh.Sum32()
	return append(b, byte(h32), byte(h32>>8), byte(h32>>16), byte(h32>>24))
}

func ( xxh XXHZero ) Sum ( b [ ] byte ) [ ] byte { h32 := xxh . Sum32 ( ) return append ( b , byte ( h32 ) , byte ( h32 >> 8 ) , byte ( h32 >> 16 ) , byte ( h32 >> 24 ) ) }

// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.

Sum appends the current hash to b and returns the resulting slice . It does not change the underlying hash state .


func (xxh *XXHZero) Reset() {
	xxh.v1 = prime32_1plus2
	xxh.v2 = prime32_2
	xxh.v3 = 0
	xxh.v4 = prime32_minus1
	xxh.totalLen = 0
	xxh.bufused = 0
}

func ( xxh * XXHZero ) Reset ( ) { xxh . v1 = prime32_1plus2 xxh . v2 = prime32_2 xxh . v3 = 0 xxh . v4 = prime32_minus1 xxh . totalLen = 0 xxh . bufused = 0 }

// Reset resets the Hash to its initial state.

Reset resets the Hash to its initial state .


func (xxh *XXHZero) Write(input []byte) (int, error) {
	if xxh.totalLen == 0 {
		xxh.Reset()
	}
	n := len(input)
	m := xxh.bufused

	xxh.totalLen += uint64(n)

	r := len(xxh.buf) - m
	if n < r {
		copy(xxh.buf[m:], input)
		xxh.bufused += len(input)
		return n, nil
	}

	p := 0
	// Causes compiler to work directly from registers instead of stack:
	v1, v2, v3, v4 := xxh.v1, xxh.v2, xxh.v3, xxh.v4
	if m > 0 {
		// some data left from previous update
		copy(xxh.buf[xxh.bufused:], input[:r])
		xxh.bufused += len(input) - r

		// fast rotl(13)
		buf := xxh.buf[:16] // BCE hint.
		v1 = rol13(v1+binary.LittleEndian.Uint32(buf[:])*prime32_2) * prime32_1
		v2 = rol13(v2+binary.LittleEndian.Uint32(buf[4:])*prime32_2) * prime32_1
		v3 = rol13(v3+binary.LittleEndian.Uint32(buf[8:])*prime32_2) * prime32_1
		v4 = rol13(v4+binary.LittleEndian.Uint32(buf[12:])*prime32_2) * prime32_1
		p = r
		xxh.bufused = 0
	}

	for n := n - 16; p <= n; p += 16 {
		sub := input[p:][:16] //BCE hint for compiler
		v1 = rol13(v1+binary.LittleEndian.Uint32(sub[:])*prime32_2) * prime32_1
		v2 = rol13(v2+binary.LittleEndian.Uint32(sub[4:])*prime32_2) * prime32_1
		v3 = rol13(v3+binary.LittleEndian.Uint32(sub[8:])*prime32_2) * prime32_1
		v4 = rol13(v4+binary.LittleEndian.Uint32(sub[12:])*prime32_2) * prime32_1
	}
	xxh.v1, xxh.v2, xxh.v3, xxh.v4 = v1, v2, v3, v4

	copy(xxh.buf[xxh.bufused:], input[p:])
	xxh.bufused += len(input) - p

	return n, nil
}

// Write adds input bytes to the Hash.
// It never returns an error.

Write adds input bytes to the Hash . It never returns an error .


// Sum32 returns the 32 bits Hash value.


func ChecksumZero(input []byte) uint32 {
	n := len(input)
	h32 := uint32(n)

	if n < 16 {
		h32 += prime32_5
	} else {
		v1 := prime32_1plus2
		v2 := prime32_2
		v3 := uint32(0)
		v4 := prime32_minus1
		p := 0
		for n := n - 16; p <= n; p += 16 {
			sub := input[p:][:16] //BCE hint for compiler
			v1 = rol13(v1+binary.LittleEndian.Uint32(sub[:])*prime32_2) * prime32_1
			v2 = rol13(v2+binary.LittleEndian.Uint32(sub[4:])*prime32_2) * prime32_1
			v3 = rol13(v3+binary.LittleEndian.Uint32(sub[8:])*prime32_2) * prime32_1
			v4 = rol13(v4+binary.LittleEndian.Uint32(sub[12:])*prime32_2) * prime32_1
		}
		input = input[p:]
		n -= p
		h32 += rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)
	}

	p := 0
	for n := n - 4; p <= n; p += 4 {
		h32 += binary.LittleEndian.Uint32(input[p:p+4]) * prime32_3
		h32 = rol17(h32) * prime32_4
	}
	for p < n {
		h32 += uint32(input[p]) * prime32_5
		h32 = rol11(h32) * prime32_1
		p++
	}

	h32 ^= h32 >> 15
	h32 *= prime32_2
	h32 ^= h32 >> 13
	h32 *= prime32_3
	h32 ^= h32 >> 16

	return h32
}

func
ChecksumZero
(
input
[
]
byte
)
uint32
{
n
:=
len
(
input
)
h32
:=
uint32
(
n
)
if
n
<
16
{
h32
+=
prime32_5
}
else
{
v1
:=
prime32_1plus2
v2
:=
prime32_2
v3
:=
uint32
(
0
)
v4
:=
prime32_minus1
p
:=
0
for
n
:=
n
16
;
p
<=
n
;
p
+=
16
{
sub
:=
input
[
p
:
]
[
:
16
]
//BCE hint for compiler
v1
=
rol13
(
v1
+
binary
.
LittleEndian
.
Uint32
(
sub
[
:
]
)
*
prime32_2
)
*
prime32_1
v2
=
rol13
(
v2
+
binary
.
LittleEndian
.
Uint32
(
sub
[
4
:
]
)
*
prime32_2
)
*
prime32_1
v3
=
rol13
(
v3
+
binary
.
LittleEndian
.
Uint32
(
sub
[
8
:
]
)
*
prime32_2
)
*
prime32_1
v4
=
rol13
(
v4
+
binary
.
LittleEndian
.
Uint32
(
sub
[
12
:
]
)
*
prime32_2
)
*
prime32_1
}
input
=
input
[
p
:
]
n
-=
p
h32
+=
rol1
(
v1
)
+
rol7
(
v2
)
+
rol12
(
v3
)
+
rol18
(
v4
)
}
p
:=
0
for
n
:=
n
4
;
p
<=
n
;
p
+=
4
{
h32
+=
binary
.
LittleEndian
.
Uint32
(
input
[
p
:
p
+
4
]
)
*
prime32_3
h32
=
rol17
(
h32
)
*
prime32_4
}
for
p
<
n
{
h32
+=
uint32
(
input
[
p
]
)
*
prime32_5
h32
=
rol11
(
h32
)
*
prime32_1
p
++
}
h32
^=
h32
>>
15
h32
*=
prime32_2
h32
^=
h32
>>
13
h32
*=
prime32_3
h32
^=
h32
>>
16
return
h32
}

// ChecksumZero returns the 32bits Hash value.

ChecksumZero returns the 32bits Hash value .


func Uint32Zero(x uint32) uint32 {
	h := prime32_5 + 4 + x*prime32_3
	h = rol17(h) * prime32_4
	h ^= h >> 15
	h *= prime32_2
	h ^= h >> 13
	h *= prime32_3
	h ^= h >> 16
	return h
}

func Uint32Zero ( x uint32 ) uint32 { h := prime32_5 + 4 + x * prime32_3 h = rol17 ( h ) * prime32_4 h ^= h >> 15 h *= prime32_2 h ^= h >> 13 h *= prime32_3 h ^= h >> 16 return h }


func UncompressBlock(src, dst []byte) (di int, err error) {
	sn := len(src)
	if sn == 0 {
		return 0, nil
	}

	di = decodeBlock(dst, src)
	if di < 0 {
		return 0, ErrInvalidSourceShortBuffer
	}
	return di, nil
}

func UncompressBlock ( src , dst [ ] byte ) ( di int , err error ) { sn := len ( src ) if sn == 0 { return 0 , nil } di = decodeBlock ( dst , src ) if di < 0 { return 0 , ErrInvalidSourceShortBuffer } return di , nil }

// UncompressBlock uncompresses the source buffer into the destination one,
// and returns the uncompressed size.
//
// The destination buffer must be sized appropriately.
//
// An error is returned if the source data is invalid or the destination buffer is too small.

UncompressBlock uncompresses the source buffer into the destination one and returns the uncompressed size . The destination buffer must be sized appropriately . An error is returned if the source data is invalid or the destination buffer is too small .


func NewReader(src io.Reader) *Reader {
	r := &Reader{src: src}
	return r
}

func NewReader ( src io . Reader ) * Reader { r := & Reader { src : src } return r }

// NewReader returns a new LZ4 frame decoder.
// No access to the underlying io.Reader is performed.

NewReader returns a new LZ4 frame decoder . No access to the underlying io . Reader is performed .


func (z *Reader) Reset(r io.Reader) {
	z.Header = Header{}
	z.pos = 0
	z.src = r
	z.zdata = z.zdata[:0]
	z.data = z.data[:0]
	z.idx = 0
	z.checksum.Reset()
}

func ( z * Reader ) Reset ( r io . Reader ) { z . Header = Header { } z . pos = 0 z . src = r z . zdata = z . zdata [ : 0 ] z . data = z . data [ : 0 ] z . idx = 0 z . checksum . Reset ( ) }

// Reset discards the Reader's state and makes it equivalent to the
// result of its original state from NewReader, but reading from r instead.
// This permits reusing a Reader rather than allocating a new one.

Reset discards the Reader s state and makes it equivalent to the result of its original state from NewReader but reading from r instead . This permits reusing a Reader rather than allocating a new one .


func (z *Reader) readUint32() (uint32, error) {
	buf := z.buf[:4]
	_, err := io.ReadFull(z.src, buf)
	x := binary.LittleEndian.Uint32(buf)
	return x, err
}

func ( z * Reader ) readUint32 ( ) ( uint32 , error ) { buf := z . buf [ : 4 ] _ , err := io . ReadFull ( z . src , buf ) x := binary . LittleEndian . Uint32 ( buf ) return x , err }

// readUint32 reads an uint32 into the supplied buffer.
// The idea is to make use of the already allocated buffers avoiding additional allocations.

readUint32 reads an uint32 into the supplied buffer . The idea is to make use of the already allocated buffers avoiding additional allocations .


func (z *Writer) Write(buf []byte) (int, error) {
	if !z.Header.done {
		if err := z.writeHeader(); err != nil {
			return 0, err
		}
	}
	if debugFlag {
		debug("input buffer len=%d index=%d", len(buf), z.idx)
	}

	zn := len(z.data)
	var n int
	for len(buf) > 0 {
		if z.idx == 0 && len(buf) >= zn {
			// Avoid a copy as there is enough data for a block.
			if err := z.compressBlock(buf[:zn]); err != nil {
				return n, err
			}
			n += zn
			buf = buf[zn:]
			continue
		}
		// Accumulate the data to be compressed.
		m := copy(z.data[z.idx:], buf)
		n += m
		z.idx += m
		buf = buf[m:]
		if debugFlag {
			debug("%d bytes copied to buf, current index %d", n, z.idx)
		}

		if z.idx < len(z.data) {
			// Buffer not filled.
			if debugFlag {
				debug("need more data for compression")
			}
			return n, nil
		}

		// Buffer full.
		if err := z.compressBlock(z.data); err != nil {
			return n, err
		}
		z.idx = 0
	}

	return n, nil
}

// Write compresses data from the supplied buffer into the underlying io.Writer.
// Write does not return until the data has been written.

Write compresses data from the supplied buffer into the underlying io . Writer . Write does not return until the data has been written .


func (z *Writer) compressBlock(data []byte) error {
	if !z.NoChecksum {
		z.checksum.Write(data)
	}

	// The compressed block size cannot exceed the input's.
	var zn int
	var err error

	if level := z.Header.CompressionLevel; level != 0 {
		zn, err = CompressBlockHC(data, z.zdata, level)
	} else {
		zn, err = CompressBlock(data, z.zdata, z.hashtable[:])
	}

	var zdata []byte
	var bLen uint32
	if debugFlag {
		debug("block compression %d => %d", len(data), zn)
	}
	if err == nil && zn > 0 && zn < len(data) {
		// Compressible and compressed size smaller than uncompressed: ok!
		bLen = uint32(zn)
		zdata = z.zdata[:zn]
	} else {
		// Uncompressed block.
		bLen = uint32(len(data)) | compressedBlockFlag
		zdata = data
	}
	if debugFlag {
		debug("block compression to be written len=%d data len=%d", bLen, len(zdata))
	}

	// Write the block.
	if err := z.writeUint32(bLen); err != nil {
		return err
	}
	written, err := z.dst.Write(zdata)
	if err != nil {
		return err
	}
	if h := z.OnBlockDone; h != nil {
		h(written)
	}

	if z.BlockChecksum {
		checksum := xxh32.ChecksumZero(zdata)
		if debugFlag {
			debug("block checksum %x", checksum)
		}
		if err := z.writeUint32(checksum); err != nil {
			return err
		}
	}
	if debugFlag {
		debug("current frame checksum %x", z.checksum.Sum32())
	}

	return nil
}


func (z *Writer) Flush() error {
	if debugFlag {
		debug("flush with index %d", z.idx)
	}
	if z.idx == 0 {
		return nil
	}

	if err := z.compressBlock(z.data[:z.idx]); err != nil {
		return err
	}
	z.idx = 0
	return nil
}

func ( z * Writer ) Flush ( ) error { if debugFlag { debug ( " " , z . idx ) } if z . idx == 0 { return nil } if err := z . compressBlock ( z . data [ : z . idx ] ) ; err != nil { return err } z . idx = 0 return nil }

// Flush flushes any pending compressed data to the underlying writer.
// Flush does not return until the data has been written.
// If the underlying writer returns an error, Flush returns that error.

Flush flushes any pending compressed data to the underlying writer . Flush does not return until the data has been written . If the underlying writer returns an error Flush returns that error .


func (z *Writer) Close() error {
	if !z.Header.done {
		if err := z.writeHeader(); err != nil {
			return err
		}
	}

	if err := z.Flush(); err != nil {
		return err
	}

	if debugFlag {
		debug("writing last empty block")
	}
	if err := z.writeUint32(0); err != nil {
		return err
	}
	if !z.NoChecksum {
		checksum := z.checksum.Sum32()
		if debugFlag {
			debug("stream checksum %x", checksum)
		}
		if err := z.writeUint32(checksum); err != nil {
			return err
		}
	}
	return nil
}

func ( z * Writer ) Close ( ) error { if ! z . Header . done { if err := z . writeHeader ( ) ; err != nil { return err } } if err := z . Flush ( ) ; err != nil { return err } if debugFlag { debug ( " " ) } if err := z . writeUint32 ( 0 ) ; err != nil { return err } if ! z . NoChecksum { checksum := z . checksum . Sum32 ( ) if debugFlag { debug ( " " , checksum ) } if err := z . writeUint32 ( checksum ) ; err != nil { return err } } return nil }

// Close closes the Writer, flushing any unwritten data to the underlying io.Writer, but does not close the underlying io.Writer.

Close closes the Writer flushing any unwritten data to the underlying io . Writer but does not close the underlying io . Writer .


func (z *Writer) Reset(w io.Writer) {
	z.Header = Header{}
	z.dst = w
	z.checksum.Reset()
	z.zdata = z.zdata[:0]
	z.data = z.data[:0]
	z.idx = 0
}

func ( z * Writer ) Reset ( w io . Writer ) { z . Header = Header { } z . dst = w z . checksum . Reset ( ) z . zdata = z . zdata [ : 0 ] z . data = z . data [ : 0 ] z . idx = 0 }

// Reset clears the state of the Writer z such that it is equivalent to its
// initial state from NewWriter, but instead writing to w.
// No access to the underlying io.Writer is performed.

Reset clears the state of the Writer z such that it is equivalent to its initial state from NewWriter but instead writing to w . No access to the underlying io . Writer is performed .


func (z *Writer) writeUint32(x uint32) error {
	buf := z.buf[:4]
	binary.LittleEndian.PutUint32(buf, x)
	_, err := z.dst.Write(buf)
	return err
}

func ( z * Writer ) writeUint32 ( x uint32 ) error { buf := z . buf [ : 4 ] binary . LittleEndian . PutUint32 ( buf , x ) _ , err := z . dst . Write ( buf ) return err }

// writeUint32 writes a uint32 to the underlying writer.

writeUint32 writes a uint32 to the underlying writer .


func Uncompress(_ *flag.FlagSet) cmdflag.Handler {
	return func(args ...string) error {
		zr := lz4.NewReader(nil)

		// Use stdin/stdout if no file provided.
		if len(args) == 0 {
			zr.Reset(os.Stdin)
			_, err := io.Copy(os.Stdout, zr)
			return err
		}

		for _, zfilename := range args {
			// Input file.
			zfile, err := os.Open(zfilename)
			if err != nil {
				return err
			}
			zinfo, err := zfile.Stat()
			if err != nil {
				return err
			}
			mode := zinfo.Mode() // use the same mode for the output file

			// Output file.
			filename := strings.TrimSuffix(zfilename, lz4.Extension)
			file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, mode)
			if err != nil {
				return err
			}
			zr.Reset(zfile)

			zfinfo, err := zfile.Stat()
			if err != nil {
				return err
			}
			var (
				size  int
				out   io.Writer = file
				zsize           = zfinfo.Size()
				bar   *progressbar.ProgressBar
			)
			if zsize > 0 {
				bar = progressbar.NewOptions64(zsize,
					// File transfers are usually slow, make sure we display the bar at 0%.
					progressbar.OptionSetRenderBlankState(true),
					// Display the filename.
					progressbar.OptionSetDescription(filename),
					progressbar.OptionClearOnFinish(),
				)
				out = io.MultiWriter(out, bar)
				zr.OnBlockDone = func(n int) {
					size += n
				}
			}

			// Uncompress.
			_, err = io.Copy(out, zr)
			if err != nil {
				return err
			}
			for _, c := range []io.Closer{zfile, file} {
				err := c.Close()
				if err != nil {
					return err
				}
			}

			if bar != nil {
				_ = bar.Clear()
				fmt.Printf("%s %d\n", zfilename, size)
			}
		}

		return nil
	}
}

// Uncompress uncompresses a set of files or from stdin to stdout.

Uncompress uncompresses a set of files or from stdin to stdout .


func Compress(fs *flag.FlagSet) cmdflag.Handler {
	var blockMaxSize string
	fs.StringVar(&blockMaxSize, "size", "4M", "block max size [64K,256K,1M,4M]")
	var blockChecksum bool
	fs.BoolVar(&blockChecksum, "bc", false, "enable block checksum")
	var streamChecksum bool
	fs.BoolVar(&streamChecksum, "sc", false, "disable stream checksum")
	var level int
	fs.IntVar(&level, "l", 0, "compression level (0=fastest)")

	return func(args ...string) error {
		sz, err := bytefmt.ToBytes(blockMaxSize)
		if err != nil {
			return err
		}

		zw := lz4.NewWriter(nil)
		zw.Header = lz4.Header{
			BlockChecksum:    blockChecksum,
			BlockMaxSize:     int(sz),
			NoChecksum:       streamChecksum,
			CompressionLevel: level,
		}

		// Use stdin/stdout if no file provided.
		if len(args) == 0 {
			zw.Reset(os.Stdout)
			_, err := io.Copy(zw, os.Stdin)
			if err != nil {
				return err
			}
			return zw.Close()
		}

		for _, filename := range args {
			// Input file.
			file, err := os.Open(filename)
			if err != nil {
				return err
			}
			finfo, err := file.Stat()
			if err != nil {
				return err
			}
			mode := finfo.Mode() // use the same mode for the output file

			// Accumulate compressed bytes num.
			var (
				zsize int
				size  = finfo.Size()
			)
			if size > 0 {
				// Progress bar setup.
				numBlocks := int(size) / zw.Header.BlockMaxSize
				bar := progressbar.NewOptions(numBlocks,
					// File transfers are usually slow, make sure we display the bar at 0%.
					progressbar.OptionSetRenderBlankState(true),
					// Display the filename.
					progressbar.OptionSetDescription(filename),
					progressbar.OptionClearOnFinish(),
				)
				zw.OnBlockDone = func(n int) {
					_ = bar.Add(1)
					zsize += n
				}
			}

			// Output file.
			zfilename := fmt.Sprintf("%s%s", filename, lz4.Extension)
			zfile, err := os.OpenFile(zfilename, os.O_CREATE|os.O_WRONLY, mode)
			if err != nil {
				return err
			}
			zw.Reset(zfile)

			// Compress.
			_, err = io.Copy(zw, file)
			if err != nil {
				return err
			}
			for _, c := range []io.Closer{zw, zfile} {
				err := c.Close()
				if err != nil {
					return err
				}
			}

			if size > 0 {
				fmt.Printf("%s %.02f%%\n", zfilename, float64(zsize)*100/float64(size))
			}
		}

		return nil
	}
}

// Compress compresses a set of files or from stdin to stdout.

Compress compresses a set of files or from stdin to stdout .


func Fuzz(data []byte) int {
	// uncompress some data
	d, err := ioutil.ReadAll(lz4.NewReader(bytes.NewReader(data)))
	if err != nil {
		return 0
	}

	// got valid compressed data
	// compress the uncompressed data
	// and compare with the original input
	buf := bytes.NewBuffer(nil)
	zw := lz4.NewWriter(buf)
	n, err := zw.Write(d)
	if err != nil {
		panic(err)
	}
	if n != len(d) {
		panic("short write")
	}
	err = zw.Close()
	if err != nil {
		panic(err)
	}

	// uncompress the newly compressed data
	ud, err := ioutil.ReadAll(lz4.NewReader(buf))
	if err != nil {
		panic(err)
	}
	if bytes.Compare(d, ud) != 0 {
		panic("not equal")
	}

	return 1
}

func
Fuzz
(
data
[
]
byte
)
int
{
// uncompress some data
d
,
err
:=
ioutil
.
ReadAll
(
lz4
.
NewReader
(
bytes
.
NewReader
(
data
)
)
)
if
err
!=
{
return
0
}
// got valid compressed data
// compress the uncompressed data
// and compare with the original input
buf
:=
bytes
.
NewBuffer
(
)
zw
:=
lz4
.
NewWriter
(
buf
)
n
,
err
:=
zw
.
Write
(
d
)
if
err
!=
{
panic
(
err
)
}
if
n
!=
len
(
d
)
{
panic
(
"
"
)
}
err
=
zw
.
Close
(
)
if
err
!=
{
panic
(
err
)
}
// uncompress the newly compressed data
ud
,
err
:=
ioutil
.
ReadAll
(
lz4
.
NewReader
(
buf
)
)
if
err
!=
{
panic
(
err
)
}
if
bytes
.
Compare
(
d
,
ud
)
!=
0
{
panic
(
"
"
)
}
return
1
}


func NewClient(address, path string, eventBus Bus) *Client {
	client := new(Client)
	client.eventBus = eventBus
	client.address = address
	client.path = path
	client.service = &ClientService{client, &sync.WaitGroup{}, false}
	return client
}

func NewClient ( address , path string , eventBus Bus ) * Client { client := new ( Client ) client . eventBus = eventBus client . address = address client . path = path client . service = & ClientService { client , & sync . WaitGroup { } , false } return client }

// NewClient - create a client object with the address and server path


func (client *Client) Subscribe(topic string, fn interface{}, serverAddr, serverPath string) {
	client.doSubscribe(topic, fn, serverAddr, serverPath, Subscribe)
}

func ( client * Client ) Subscribe ( topic string , fn interface { } , serverAddr , serverPath string ) { client . doSubscribe ( topic , fn , serverAddr , serverPath , Subscribe ) }

//Subscribe subscribes to a topic in a remote event bus


func (client *Client) Start() error {
	var err error
	service := client.service
	if !service.started {
		server := rpc.NewServer()
		server.Register(service)
		server.HandleHTTP(client.path, "/debug"+client.path)
		l, err := net.Listen("tcp", client.address)
		if err == nil {
			service.wg.Add(1)
			service.started = true
			go http.Serve(l, nil)
		}
	} else {
		err = errors.New("Client service already started")
	}
	return err
}

func ( client * Client ) Start ( ) error { var err error service := client . service if ! service . started { server := rpc . NewServer ( ) server . Register ( service ) server . HandleHTTP ( client . path , " " + client . path ) l , err := net . Listen ( " " , client . address ) if err == nil { service . wg . Add ( 1 ) service . started = true go http . Serve ( l , nil ) } } else { err = errors . New ( " " ) } return err }

// Start - starts the client service to listen to remote events


func (service *ClientService) PushEvent(arg *ClientArg, reply *bool) error {
	service.client.eventBus.Publish(arg.Topic, arg.Args...)
	*reply = true
	return nil
}

func ( service * ClientService ) PushEvent ( arg * ClientArg , reply * bool ) error { service . client . eventBus . Publish ( arg . Topic , arg . Args ... ) * reply = true return nil }

// PushEvent - exported service to listening to remote events


func New() Bus {
	b := &EventBus{
		make(map[string][]*eventHandler),
		sync.Mutex{},
		sync.WaitGroup{},
	}
	return Bus(b)
}

func New ( ) Bus { b := & EventBus { make ( map [ string ] [ ] * eventHandler ) , sync . Mutex { } , sync . WaitGroup { } , } return Bus ( b ) }

// New returns new EventBus with empty handlers.

New returns new EventBus with empty handlers .


func (bus *EventBus) doSubscribe(topic string, fn interface{}, handler *eventHandler) error {
	bus.lock.Lock()
	defer bus.lock.Unlock()
	if !(reflect.TypeOf(fn).Kind() == reflect.Func) {
		return fmt.Errorf("%s is not of type reflect.Func", reflect.TypeOf(fn).Kind())
	}
	bus.handlers[topic] = append(bus.handlers[topic], handler)
	return nil
}

func ( bus * EventBus ) doSubscribe ( topic string , fn interface { } , handler * eventHandler ) error { bus . lock . Lock ( ) defer bus . lock . Unlock ( ) if ! ( reflect . TypeOf ( fn ) . Kind ( ) == reflect . Func ) { return fmt . Errorf ( " " , reflect . TypeOf ( fn ) . Kind ( ) ) } bus . handlers [ topic ] = append ( bus . handlers [ topic ] , handler ) return nil }

// doSubscribe handles the subscription logic and is utilized by the public Subscribe functions


func (bus *EventBus) Subscribe(topic string, fn interface{}) error {
	return bus.doSubscribe(topic, fn, &eventHandler{
		reflect.ValueOf(fn), false, false, false, sync.Mutex{},
	})
}

func ( bus * EventBus ) Subscribe ( topic string , fn interface { } ) error { return bus . doSubscribe ( topic , fn , & eventHandler { reflect . ValueOf ( fn ) , false , false , false , sync . Mutex { } , } ) }

// Subscribe subscribes to a topic.
// Returns error if `fn` is not a function.

Subscribe subscribes to a topic . Returns error if fn is not a function .


func (bus *EventBus) HasCallback(topic string) bool {
	bus.lock.Lock()
	defer bus.lock.Unlock()
	_, ok := bus.handlers[topic]
	if ok {
		return len(bus.handlers[topic]) > 0
	}
	return false
}

func ( bus * EventBus ) HasCallback ( topic string ) bool { bus . lock . Lock ( ) defer bus . lock . Unlock ( ) _ , ok := bus . handlers [ topic ] if ok { return len ( bus . handlers [ topic ] ) > 0 } return false }

// HasCallback returns true if exists any callback subscribed to the topic.

HasCallback returns true if exists any callback subscribed to the topic .


func (bus *EventBus) Unsubscribe(topic string, handler interface{}) error {
	bus.lock.Lock()
	defer bus.lock.Unlock()
	if _, ok := bus.handlers[topic]; ok && len(bus.handlers[topic]) > 0 {
		bus.removeHandler(topic, bus.findHandlerIdx(topic, reflect.ValueOf(handler)))
		return nil
	}
	return fmt.Errorf("topic %s doesn't exist", topic)
}

func ( bus * EventBus ) Unsubscribe ( topic string , handler interface { } ) error { bus . lock . Lock ( ) defer bus . lock . Unlock ( ) if _ , ok := bus . handlers [ topic ] ; ok && len ( bus . handlers [ topic ] ) > 0 { bus . removeHandler ( topic , bus . findHandlerIdx ( topic , reflect . ValueOf ( handler ) ) ) return nil } return fmt . Errorf ( " " , topic ) }

// Unsubscribe removes callback defined for a topic.
// Returns error if there are no callbacks subscribed to the topic.

Unsubscribe removes callback defined for a topic . Returns error if there are no callbacks subscribed to the topic .


func (bus *EventBus) Publish(topic string, args ...interface{}) {
	bus.lock.Lock() // will unlock if handler is not found or always after setUpPublish
	defer bus.lock.Unlock()
	if handlers, ok := bus.handlers[topic]; ok && 0 < len(handlers) {
		// Handlers slice may be changed by removeHandler and Unsubscribe during iteration,
		// so make a copy and iterate the copied slice.
		copyHandlers := make([]*eventHandler, 0, len(handlers))
		copyHandlers = append(copyHandlers, handlers...)
		for i, handler := range copyHandlers {
			if handler.flagOnce {
				bus.removeHandler(topic, i)
			}
			if !handler.async {
				bus.doPublish(handler, topic, args...)
			} else {
				bus.wg.Add(1)
				if handler.transactional {
					handler.Lock()
				}
				go bus.doPublishAsync(handler, topic, args...)
			}
		}
	}
}

// Publish executes callback defined for a topic. Any additional argument will be transferred to the callback.

Publish executes callback defined for a topic . Any additional argument will be transferred to the callback .


func NewNetworkBus(address, path string) *NetworkBus {
	bus := new(NetworkBus)
	bus.sharedBus = New()
	bus.Server = NewServer(address, path, bus.sharedBus)
	bus.Client = NewClient(address, path, bus.sharedBus)
	bus.service = &NetworkBusService{&sync.WaitGroup{}, false}
	bus.address = address
	bus.path = path
	return bus
}

func NewNetworkBus ( address , path string ) * NetworkBus { bus := new ( NetworkBus ) bus . sharedBus = New ( ) bus . Server = NewServer ( address , path , bus . sharedBus ) bus . Client = NewClient ( address , path , bus . sharedBus ) bus . service = & NetworkBusService { & sync . WaitGroup { } , false } bus . address = address bus . path = path return bus }

// NewNetworkBus - returns a new network bus object at the server address and path


func (networkBus *NetworkBus) Start() error {
	var err error
	service := networkBus.service
	clientService := networkBus.Client.service
	serverService := networkBus.Server.service
	if !service.started {
		server := rpc.NewServer()
		server.RegisterName("ServerService", serverService)
		server.RegisterName("ClientService", clientService)
		server.HandleHTTP(networkBus.path, "/debug"+networkBus.path)
		l, e := net.Listen("tcp", networkBus.address)
		if e != nil {
			err = fmt.Errorf("listen error: %v", e)
		}
		service.wg.Add(1)
		go http.Serve(l, nil)
	} else {
		err = errors.New("Server bus already started")
	}
	return err
}

func ( networkBus * NetworkBus ) Start ( ) error { var err error service := networkBus . service clientService := networkBus . Client . service serverService := networkBus . Server . service if ! service . started { server := rpc . NewServer ( ) server . RegisterName ( " " , serverService ) server . RegisterName ( " " , clientService ) server . HandleHTTP ( networkBus . path , " " + networkBus . path ) l , e := net . Listen ( " " , networkBus . address ) if e != nil { err = fmt . Errorf ( " " , e ) } service . wg . Add ( 1 ) go http . Serve ( l , nil ) } else { err = errors . New ( " " ) } return err }

// Start - helper method to serve a network bus service


func NewServer(address, path string, eventBus Bus) *Server {
	server := new(Server)
	server.eventBus = eventBus
	server.address = address
	server.path = path
	server.subscribers = make(map[string][]*SubscribeArg)
	server.service = &ServerService{server, &sync.WaitGroup{}, false}
	return server
}

func NewServer ( address , path string , eventBus Bus ) * Server { server := new ( Server ) server . eventBus = eventBus server . address = address server . path = path server . subscribers = make ( map [ string ] [ ] * SubscribeArg ) server . service = & ServerService { server , & sync . WaitGroup { } , false } return server }

// NewServer - create a new Server at the address and path


func (server *Server) HasClientSubscribed(arg *SubscribeArg) bool {
	if topicSubscribers, ok := server.subscribers[arg.Topic]; ok {
		for _, topicSubscriber := range topicSubscribers {
			if *topicSubscriber == *arg {
				return true
			}
		}
	}
	return false
}

func ( server * Server ) HasClientSubscribed ( arg * SubscribeArg ) bool { if topicSubscribers , ok := server . subscribers [ arg . Topic ] ; ok { for _ , topicSubscriber := range topicSubscribers { if * topicSubscriber == * arg { return true } } } return false }

// HasClientSubscribed - True if a client subscribed to this server with the same topic


func (server *Server) Start() error {
	var err error
	service := server.service
	if !service.started {
		rpcServer := rpc.NewServer()
		rpcServer.Register(service)
		rpcServer.HandleHTTP(server.path, "/debug"+server.path)
		l, e := net.Listen("tcp", server.address)
		if e != nil {
			err = e
			fmt.Errorf("listen error: %v", e)
		}
		service.started = true
		service.wg.Add(1)
		go http.Serve(l, nil)
	} else {
		err = errors.New("Server bus already started")
	}
	return err
}

func ( server * Server ) Start ( ) error { var err error service := server . service if ! service . started { rpcServer := rpc . NewServer ( ) rpcServer . Register ( service ) rpcServer . HandleHTTP ( server . path , " " + server . path ) l , e := net . Listen ( " " , server . address ) if e != nil { err = e fmt . Errorf ( " " , e ) } service . started = true service . wg . Add ( 1 ) go http . Serve ( l , nil ) } else { err = errors . New ( " " ) } return err }

// Start - starts a service for remote clients to subscribe to events


func (service *ServerService) Register(arg *SubscribeArg, success *bool) error {
	subscribers := service.server.subscribers
	if !service.server.HasClientSubscribed(arg) {
		rpcCallback := service.server.rpcCallback(arg)
		switch arg.SubscribeType {
		case Subscribe:
			service.server.eventBus.Subscribe(arg.Topic, rpcCallback)
		case SubscribeOnce:
			service.server.eventBus.SubscribeOnce(arg.Topic, rpcCallback)
		}
		var topicSubscribers []*SubscribeArg
		if _, ok := subscribers[arg.Topic]; ok {
			topicSubscribers = []*SubscribeArg{arg}
		} else {
			topicSubscribers = subscribers[arg.Topic]
			topicSubscribers = append(topicSubscribers, arg)
		}
		subscribers[arg.Topic] = topicSubscribers
	}
	*success = true
	return nil
}

func ( service * ServerService ) Register ( arg * SubscribeArg , success * bool ) error { subscribers := service . server . subscribers if ! service . server . HasClientSubscribed ( arg ) { rpcCallback := service . server . rpcCallback ( arg ) switch arg . SubscribeType { case Subscribe : service . server . eventBus . Subscribe ( arg . Topic , rpcCallback ) case SubscribeOnce : service . server . eventBus . SubscribeOnce ( arg . Topic , rpcCallback ) } var topicSubscribers [ ] * SubscribeArg if _ , ok := subscribers [ arg . Topic ] ; ok { topicSubscribers = [ ] * SubscribeArg { arg } } else { topicSubscribers = subscribers [ arg . Topic ] topicSubscribers = append ( topicSubscribers , arg ) } subscribers [ arg . Topic ] = topicSubscribers } * success = true return nil }

// Register - Registers a remote handler to this event bus
// for a remote subscribe - a given client address only needs to subscribe once
// event will be republished in local event bus

Register - Registers a remote handler to this event bus for a remote subscribe - a given client address only needs to subscribe once event will be republished in local event bus


func (p GTLDPeriod) Valid(when time.Time) error {
	// NOTE: We can throw away the errors from time.Parse in this function because
	// the zlint-gtld-update command only writes entries to the generated gTLD map
	// after the dates have been verified as parseable
	notBefore, _ := time.Parse(GTLDPeriodDateFormat, p.DelegationDate)
	if when.Before(notBefore) {
		return fmt.Errorf(`gTLD ".%s" is not valid until %s`,
			p.GTLD, p.DelegationDate)
	}
	// The removal date may be empty. We only need to check `when` against the
	// removal when it isn't empty
	if p.RemovalDate != "" {
		notAfter, _ := time.Parse(GTLDPeriodDateFormat, p.RemovalDate)
		if when.After(notAfter) {
			return fmt.Errorf(`gTLD ".%s" is not valid after %s`,
				p.GTLD, p.RemovalDate)
		}
	}
	return nil
}

// Valid determines if the provided `when` time is within the GTLDPeriod for the
// gTLD. E.g. whether a certificate issued at `when` with a subject identifier
// using the specified gTLD can be considered a valid use of the gTLD.

Valid determines if the provided when time is within the GTLDPeriod for the gTLD . E . g . whether a certificate issued at when with a subject identifier using the specified gTLD can be considered a valid use of the gTLD .


func HasValidTLD(domain string, when time.Time) bool {
	labels := strings.Split(strings.ToLower(domain), ".")
	rightLabel := labels[len(labels)-1]
	// if the rightmost label is not present in the tldMap, it isn't valid and
	// never was.
	if tldPeriod, present := tldMap[rightLabel]; !present {
		return false
	} else if tldPeriod.Valid(when) != nil {
		// If the TLD exists but the date is outside of the gTLD's validity period
		// then it is not a valid TLD.
		return false
	}
	// Otherwise the TLD exists, and was a valid TLD delegated in the root DNS
	// at the time of the given date.
	return true
}

// HasValidTLD checks that a domain ends in a valid TLD that was delegated in
// the root DNS at the time specified.

HasValidTLD checks that a domain ends in a valid TLD that was delegated in the root DNS at the time specified .


func IsInTLDMap(label string) bool {
	label = strings.ToLower(label)
	if _, ok := tldMap[label]; ok {
		return true
	} else {
		return false
	}
}

func IsInTLDMap ( label string ) bool { label = strings . ToLower ( label ) if _ , ok := tldMap [ label ] ; ok { return true } else { return false } }

// IsInTLDMap checks that a label is present in the TLD map. It does not
// consider the TLD's validity period and whether the TLD may have been removed,
// only whether it was ever a TLD that was delegated.

IsInTLDMap checks that a label is present in the TLD map . It does not consider the TLD s validity period and whether the TLD may have been removed only whether it was ever a TLD that was delegated .


func (l *arpaMalformedIP) Execute(c *x509.Certificate) *LintResult {
	for _, name := range c.DNSNames {
		name = strings.ToLower(name)
		var err error
		if strings.HasSuffix(name, rdnsIPv4Suffix) {
			// If the name has the in-addr.arpa suffix then it should be an IPv4 reverse
			// DNS name.
			err = lintReversedIPAddressLabels(name, false)
		} else if strings.HasSuffix(name, rdnsIPv6Suffix) {
			// If the name has the ip6.arpa suffix then it should be an IPv6 reverse
			// DNS name.
			err = lintReversedIPAddressLabels(name, true)
		}
		// Return the first error as a negative lint result
		if err != nil {
			return &LintResult{
				Status:  Warn,
				Details: err.Error(),
			}
		}
	}

	return &LintResult{
		Status: Pass,
	}
}

// Execute will check the given certificate to ensure that all of the DNS
// subject alternate names that specify a reverse DNS name under the respective
// IPv4 or IPv6 arpa zones are well formed. A Warn LintResult is returned if
// the name is in a reverse DNS zone but has the wrong number of labels.

Execute will check the given certificate to ensure that all of the DNS subject alternate names that specify a reverse DNS name under the respective IPv4 or IPv6 arpa zones are well formed . A Warn LintResult is returned if the name is in a reverse DNS zone but has the wrong number of labels .


func lintReversedIPAddressLabels(name string, ipv6 bool) error {
	numRequiredLabels := rdnsIPv4Labels
	zoneSuffix := rdnsIPv4Suffix

	if ipv6 {
		numRequiredLabels = rdnsIPv6Labels
		zoneSuffix = rdnsIPv6Suffix
	}

	// Strip off the zone suffix to get only the reversed IP address
	ipName := strings.TrimSuffix(name, zoneSuffix)

	// A well encoded IPv4 or IPv6 reverse DNS name will have the correct number
	// of labels to express the address
	ipLabels := strings.Split(ipName, ".")
	if len(ipLabels) != numRequiredLabels {
		return fmt.Errorf(
			"name %q has too few leading labels (%d vs %d) to be a reverse DNS entry "+
				"in the %q zone.",
			name, len(ipLabels), numRequiredLabels, zoneSuffix)
	}

	// Reverse the IP labels and try to parse an IP address
	var ip net.IP
	if ipv6 {
		ip = reversedLabelsToIPv6(ipLabels)
	} else {
		ip = reversedLabelsToIPv4(ipLabels)
	}

	// If the result isn't an IP then a warning should be generated
	if ip == nil {
		return fmt.Errorf(
			"the first %d labels of name %q did not parse as a reversed IP address",
			numRequiredLabels, name)
	}

	// Otherwise return no error - checking the actual value of the IP is left to
	// `lint_subject_contains_reserved_arpa_ip.go`.
	return nil
}

// lintReversedIPAddressLabels lints the given name as either a reversed IPv4 or
// IPv6 address under the respective ARPA zone based on the address class. An
// error is returned if there aren't enough labels in the name after removing
// the relevant arpa suffix.

lintReversedIPAddressLabels lints the given name as either a reversed IPv4 or IPv6 address under the respective ARPA zone based on the address class . An error is returned if there aren t enough labels in the name after removing the relevant arpa suffix .


func CheckRDNSequenceWhiteSpace(raw []byte) (leading, trailing bool, err error) {
	var seq pkix.RDNSequence
	if _, err = asn1.Unmarshal(raw, &seq); err != nil {
		return
	}
	for _, rdn := range seq {
		for _, atv := range rdn {
			if !IsNameAttribute(atv.Type) {
				continue
			}
			value, ok := atv.Value.(string)
			if !ok {
				continue
			}
			if leftStrip := strings.TrimLeftFunc(value, unicode.IsSpace); leftStrip != value {
				leading = true
			}
			if rightStrip := strings.TrimRightFunc(value, unicode.IsSpace); rightStrip != value {
				trailing = true
			}
		}
	}
	return
}

func CheckRDNSequenceWhiteSpace ( raw [ ] byte ) ( leading , trailing bool , err error ) { var seq pkix . RDNSequence if _ , err = asn1 . Unmarshal ( raw , & seq ) ; err != nil { return } for _ , rdn := range seq { for _ , atv := range rdn { if ! IsNameAttribute ( atv . Type ) { continue } value , ok := atv . Value . ( string ) if ! ok { continue } if leftStrip := strings . TrimLeftFunc ( value , unicode . IsSpace ) ; leftStrip != value { leading = true } if rightStrip := strings . TrimRightFunc ( value , unicode . IsSpace ) ; rightStrip != value { trailing = true } } } return }

// CheckRDNSequenceWhiteSpace returns true if there is leading or trailing
// whitespace in any name attribute in the sequence, respectively.

CheckRDNSequenceWhiteSpace returns true if there is leading or trailing whitespace in any name attribute in the sequence respectively .


func IsIA5String(raw []byte) bool {
	for _, b := range raw {
		i := int(b)
		if i > 127 || i < 0 {
			return false
		}
	}
	return true
}

func IsIA5String ( raw [ ] byte ) bool { for _ , b := range raw { i := int ( b ) if i > 127 || i < 0 { return false } } return true }

// IsIA5String returns true if raw is an IA5String, and returns false otherwise.

IsIA5String returns true if raw is an IA5String and returns false otherwise .


func AllAlternateNameWithTagAreIA5(ext *pkix.Extension, tag int) (bool, error) {
	var seq asn1.RawValue
	var err error
	// Unmarshal the extension as a sequence
	if _, err = asn1.Unmarshal(ext.Value, &seq); err != nil {
		return false, err
	}
	// Ensure the sequence matches what we expect for SAN/IAN
	if !seq.IsCompound || seq.Tag != asn1.TagSequence || seq.Class != asn1.ClassUniversal {
		err = asn1.StructuralError{Msg: "bad alternate name sequence"}
		return false, err
	}

	// Iterate over the sequence and look for items tagged with tag
	rest := seq.Bytes
	for len(rest) > 0 {
		var v asn1.RawValue
		rest, err = asn1.Unmarshal(rest, &v)
		if err != nil {
			return false, err
		}
		if v.Tag == tag {
			if !IsIA5String(v.Bytes) {
				return false, nil
			}
		}
	}

	return true, nil
}

// AllAlternateNameWithTagAreIA5 returns true if all sequence members with the
// given tag are encoded as IA5 strings, and false otherwise. If it encounters
// errors parsing asn1, err will be non-nil.

AllAlternateNameWithTagAreIA5 returns true if all sequence members with the given tag are encoded as IA5 strings and false otherwise . If it encounters errors parsing asn1 err will be non - nil .


func IsEV(in []asn1.ObjectIdentifier) bool {
	for _, oid := range in {
		if _, ok := evoids[oid.String()]; ok {
			return true
		}
	}
	return false
}

func IsEV ( in [ ] asn1 . ObjectIdentifier ) bool { for _ , oid := range in { if _ , ok := evoids [ oid . String ( ) ] ; ok { return true } } return false }

// IsEV returns true if the input is a known Extended Validation OID.

IsEV returns true if the input is a known Extended Validation OID .


func (l *onionNotEV) Execute(c *x509.Certificate) *LintResult {
	/*
	 * Effective May 1, 2015, each CA SHALL revoke all unexpired Certificates with an
	 * Internal Name using onion as the right-most label in an entry in the
	 * subjectAltName Extension or commonName field unless such Certificate was
	 * issued in accordance with Appendix F of the EV Guidelines.
	 */
	if !util.IsEV(c.PolicyIdentifiers) {
		return &LintResult{
			Status: Error,
			Details: fmt.Sprintf(
				"certificate contains one or more %s subject domains but is not an EV certificate",
				onionTLD),
		}
	}
	return &LintResult{Status: Pass}
}

// Execute returns an Error LintResult if the certificate is not an EV
// certificate. CheckApplies has already verified the certificate contains one
// or more `.onion` subjects and so it must be an EV certificate.

Execute returns an Error LintResult if the certificate is not an EV certificate . CheckApplies has already verified the certificate contains one or more . onion subjects and so it must be an EV certificate .


func getData(url string) ([]byte, error) {
	resp, err := httpClient.Get(url)
	if err != nil {
		return nil, fmt.Errorf("unable to fetch data from %q : %s",
			url, err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("unexpected status code fetching data "+
			"from %q : expected status %d got %d",
			url, http.StatusOK, resp.StatusCode)
	}

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("unexpected error reading response "+
			"body from %q : %s",
			url, err)
	}
	return respBody, nil
}

func getData ( url string ) ( [ ] byte , error ) { resp , err := httpClient . Get ( url ) if err != nil { return nil , fmt . Errorf ( " " , url , err ) } defer resp . Body . Close ( ) if resp . StatusCode != http . StatusOK { return nil , fmt . Errorf ( " " + " " , url , http . StatusOK , resp . StatusCode ) } respBody , err := ioutil . ReadAll ( resp . Body ) if err != nil { return nil , fmt . Errorf ( " " + " " , url , err ) } return respBody , nil }

// getData fetches the response body bytes from an HTTP get to the provider url,
// or returns an error.

getData fetches the response body bytes from an HTTP get to the provider url or returns an error .


func getGTLDData() ([]util.GTLDPeriod, error) {
	respBody, err := getData(ICANN_GTLD_JSON)
	if err != nil {
		return nil, fmt.Errorf("error getting ICANN gTLD JSON : %s", err)
	}

	var results struct {
		GTLDs []util.GTLDPeriod
	}
	if err := json.Unmarshal(respBody, &results); err != nil {
		return nil, fmt.Errorf("unexpected error unmarshaling ICANN gTLD JSON response "+
			"body from %q : %s",
			ICANN_GTLD_JSON, err)
	}
	return results.GTLDs, nil
}

func getGTLDData ( ) ( [ ] util . GTLDPeriod , error ) { respBody , err := getData ( ICANN_GTLD_JSON ) if err != nil { return nil , fmt . Errorf ( " " , err ) } var results struct { GTLDs [ ] util . GTLDPeriod } if err := json . Unmarshal ( respBody , & results ) ; err != nil { return nil , fmt . Errorf ( " " + " " , ICANN_GTLD_JSON , err ) } return results . GTLDs , nil }

// getGTLDData fetches the ICANN_GTLD_JSON and parses it into a list of
// util.GTLDPeriod objects, or returns an error. The gTLDEntries are returned
// as-is and may contain entries that were never delegated from the root DNS.

getGTLDData fetches the ICANN_GTLD_JSON and parses it into a list of util . GTLDPeriod objects or returns an error . The gTLDEntries are returned as - is and may contain entries that were never delegated from the root DNS .


func delegatedGTLDs(entries []util.GTLDPeriod) []util.GTLDPeriod {
	var results []util.GTLDPeriod
	for _, gTLD := range entries {
		if gTLD.DelegationDate == "" {
			continue
		}
		results = append(results, gTLD)
	}
	return results
}

func delegatedGTLDs ( entries [ ] util . GTLDPeriod ) [ ] util . GTLDPeriod { var results [ ] util . GTLDPeriod for _ , gTLD := range entries { if gTLD . DelegationDate == " " { continue } results = append ( results , gTLD ) } return results }

// delegatedGTLDs filters the provided list of GTLDPeriods removing any entries
// that were never delegated from the root DNS.

delegatedGTLDs filters the provided list of GTLDPeriods removing any entries that were never delegated from the root DNS .


func validateGTLDs(entries []util.GTLDPeriod) error {
	for _, gTLD := range entries {
		// All entries should have a valid delegation date
		if _, err := time.Parse(util.GTLDPeriodDateFormat, gTLD.DelegationDate); err != nil {
			return err
		}
		// a gTLD that has not been removed has an empty RemovalDate and that's OK
		if _, err := time.Parse(util.GTLDPeriodDateFormat, gTLD.RemovalDate); gTLD.RemovalDate != "" && err != nil {
			return err
		}
	}
	return nil
}

// validateGTLDs checks that all entries have a valid parseable DelegationDate
// string, and if not-empty, a valid parseable RemovalDate string. This function
// assumes an entry with an empty DelegationDate is an error. Use
// `delegatedGTLDs` to filter out entries that were never delegated before
// validating.

validateGTLDs checks that all entries have a valid parseable DelegationDate string and if not - empty a valid parseable RemovalDate string . This function assumes an entry with an empty DelegationDate is an error . Use delegatedGTLDs to filter out entries that were never delegated before validating .


func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [flags]\n", os.Args[0])
		flag.PrintDefaults()
	}
	flag.Parse()
	log.SetLevel(log.InfoLevel)
}

func init ( ) { flag . Usage = func ( ) { fmt . Fprintf ( os . Stderr , " \n " , os . Args [ 0 ] ) flag . PrintDefaults ( ) } flag . Parse ( ) log . SetLevel ( log . InfoLevel ) }


func IsNameAttribute(oid asn1.ObjectIdentifier) bool {
	if len(oid) != 4 {
		return false
	}
	if !nameAttributePrefix.Equal(oid[0:3]) {
		return false
	}
	_, ok := nameAttributeLeaves[oid[3]]
	return ok
}

func IsNameAttribute ( oid asn1 . ObjectIdentifier ) bool { if len ( oid ) != 4 { return false } if ! nameAttributePrefix . Equal ( oid [ 0 : 3 ] ) { return false } _ , ok := nameAttributeLeaves [ oid [ 3 ] ] return ok }

// IsNameAttribute returns true if the given ObjectIdentifier corresponds with
// the type of any name attribute for PKIX.

IsNameAttribute returns true if the given ObjectIdentifier corresponds with the type of any name attribute for PKIX .


func (e LintStatus) MarshalJSON() ([]byte, error) {
	s := e.String()
	return json.Marshal(s)
}

func ( e LintStatus ) MarshalJSON ( ) ( [ ] byte , error ) { s := e . String ( ) return json . Marshal ( s ) }

// MarshalJSON implements the json.Marshaler interface.

MarshalJSON implements the json . Marshaler interface .


func (e LintStatus) String() string {
	switch e {
	case NA:
		return "NA"
	case NE:
		return "NE"
	case Pass:
		return "pass"
	case Notice:
		return "info"
	case Warn:
		return "warn"
	case Error:
		return "error"
	case Fatal:
		return "fatal"
	default:
		return ""
	}
}

func ( e LintStatus ) String ( ) string { switch e { case NA : return " " case NE : return " " case Pass : return " " case Notice : return " " case Warn : return " " case Error : return " " case Fatal : return " " default : return " " } }

// String returns the canonical representation of a LintStatus as a string.

String returns the canonical representation of a LintStatus as a string .


func EncodeLintDescriptionsToJSON(w io.Writer) {
	enc := json.NewEncoder(w)
	enc.SetEscapeHTML(false)
	for _, lint := range lints.Lints {
		enc.Encode(lint)
	}
}

func EncodeLintDescriptionsToJSON ( w io . Writer ) { enc := json . NewEncoder ( w ) enc . SetEscapeHTML ( false ) for _ , lint := range lints . Lints { enc . Encode ( lint ) } }

// EncodeLintDescriptionsToJSON outputs a description of each lint as JSON
// object, one object per line.

EncodeLintDescriptionsToJSON outputs a description of each lint as JSON object one object per line .


func LintCertificate(c *x509.Certificate) *ResultSet {
	// Instead of panicing on nil certificate, just returns nil and let the client
	// panic when accessing ZLint, if they're into panicing.
	if c == nil {
		return nil
	}

	// Run all tests
	res := new(ResultSet)
	res.execute(c)
	res.Version = Version
	res.Timestamp = time.Now().Unix()
	return res
}

// LintCertificate runs all registered lints on c, producing a ZLint.

LintCertificate runs all registered lints on c producing a ZLint .


func (l *torValidityTooLarge) CheckApplies(c *x509.Certificate) bool {
	return util.IsSubscriberCert(c) && util.CertificateSubjInTLD(c, onionTLD)
}

func ( l * torValidityTooLarge ) CheckApplies ( c * x509 . Certificate ) bool { return util . IsSubscriberCert ( c ) && util . CertificateSubjInTLD ( c , onionTLD ) }

// CheckApplies returns true if the certificate is a subscriber certificate that
// contains a subject name ending in `.onion`.

CheckApplies returns true if the certificate is a subscriber certificate that contains a subject name ending in . onion .


func failResult(format string, args ...interface{}) *LintResult {
	return &LintResult{
		Status:  Error,
		Details: fmt.Sprintf(format, args...),
	}
}

func failResult ( format string , args ... interface { } ) * LintResult { return & LintResult { Status : Error , Details : fmt . Sprintf ( format , args ... ) , } }

// failResult is a small utility function for creating a failed lint result.

failResult is a small utility function for creating a failed lint result .


func (l *Lint) CheckEffective(c *x509.Certificate) bool {
	if l.EffectiveDate.IsZero() || !l.EffectiveDate.After(c.NotBefore) {
		return true
	}
	return false
}

func ( l * Lint ) CheckEffective ( c * x509 . Certificate ) bool { if l . EffectiveDate . IsZero ( ) || ! l . EffectiveDate . After ( c . NotBefore ) { return true } return false }

// CheckEffective returns true if c was issued on or after the EffectiveDate. If
// EffectiveDate is zero, CheckEffective always returns true.

CheckEffective returns true if c was issued on or after the EffectiveDate . If EffectiveDate is zero CheckEffective always returns true .


func GetExtFromCert(cert *x509.Certificate, oid asn1.ObjectIdentifier) *pkix.Extension {
	for i := range cert.Extensions {
		if oid.Equal(cert.Extensions[i].Id) {
			return &(cert.Extensions[i])
		}
	}
	return nil
}

func GetExtFromCert ( cert * x509 . Certificate , oid asn1 . ObjectIdentifier ) * pkix . Extension { for i := range cert . Extensions { if oid . Equal ( cert . Extensions [ i ] . Id ) { return & ( cert . Extensions [ i ] ) } } return nil }

// GetExtFromCert returns the extension with the matching OID, if present. If
// the extension if not present, it returns nil.

GetExtFromCert returns the extension with the matching OID if present . If the extension if not present it returns nil .


func TypeInName(name *pkix.Name, oid asn1.ObjectIdentifier) bool {
	for _, v := range name.Names {
		if oid.Equal(v.Type) {
			return true
		}
	}
	return false
}

func TypeInName ( name * pkix . Name , oid asn1 . ObjectIdentifier ) bool { for _ , v := range name . Names { if oid . Equal ( v . Type ) { return true } } return false }

// Helper function that checks for a name type in a pkix.Name

Helper function that checks for a name type in a pkix . Name


func GetMappedPolicies(polMap *pkix.Extension) (out [][2]asn1.ObjectIdentifier, err error) {
	if polMap == nil {
		return nil, errors.New("policyMap: null pointer")
	}
	var outSeq, inSeq asn1.RawValue

	empty, err := asn1.Unmarshal(polMap.Value, &outSeq) //strip outer sequence tag/length should be nothing extra
	if err != nil || len(empty) != 0 || outSeq.Class != 0 || outSeq.Tag != 16 || outSeq.IsCompound == false {
		return nil, errors.New("policyMap: Could not unmarshal outer sequence.")
	}

	for done := false; !done; { //loop through SEQUENCE OF
		outSeq.Bytes, err = asn1.Unmarshal(outSeq.Bytes, &inSeq) //extract next inner SEQUENCE (OID pair)
		if err != nil || inSeq.Class != 0 || inSeq.Tag != 16 || inSeq.IsCompound == false {
			err = errors.New("policyMap: Could not unmarshal inner sequence.")
			return
		}
		if len(outSeq.Bytes) == 0 { //nothing remaining to parse, stop looping after
			done = true
		}

		var oidIssue, oidSubject asn1.ObjectIdentifier
		var restIn asn1.RawContent
		restIn, err = asn1.Unmarshal(inSeq.Bytes, &oidIssue) //extract first inner CertPolicyId (issuer domain)
		if err != nil || len(restIn) == 0 {
			err = errors.New("policyMap: Could not unmarshal inner sequence.")
			return
		}

		empty, err = asn1.Unmarshal(restIn, &oidSubject) //extract second inner CertPolicyId (subject domain)
		if err != nil || len(empty) != 0 {
			err = errors.New("policyMap: Could not unmarshal inner sequence.")
			return
		}

		//append found OIDs
		out = append(out, [2]asn1.ObjectIdentifier{oidIssue, oidSubject})
	}

	return
}

//helper function to parse policyMapping extensions, returns slices of CertPolicyIds separated by domain

helper function to parse policyMapping extensions returns slices of CertPolicyIds separated by domain


func printJSON(v interface{}) {
	w := json.NewEncoder(os.Stdout)
	w.SetIndent("", "\t")
	err := w.Encode(v)
	if err != nil {
		panic(err)
	}
}

func printJSON ( v interface { } ) { w := json . NewEncoder ( os . Stdout ) w . SetIndent ( " " , " \t " ) err := w . Encode ( v ) if err != nil { panic ( err ) } }

// printJSON prints v as JSON encoded with indent to stdout. It panics on any error.

printJSON prints v as JSON encoded with indent to stdout . It panics on any error .


func (u *URI) UnmarshalJSON(data []byte) error {
	// Ignore null, like in the main JSON package.
	if string(data) == "null" {
		return nil
	}
	var s string
	err := json.Unmarshal(data, &s)
	if err != nil {
		return err
	}
	u.URL, err = url.Parse(s)
	return err
}

// UnmarshalJSON implements the json.Unmarshaler interface.
// The URI is expected to be a quoted string.

UnmarshalJSON implements the json . Unmarshaler interface . The URI is expected to be a quoted string .


func NewClient(httpClient *http.Client) *Client {
	return &Client{
		client: graphql.NewClient("https://api.github.com/graphql", httpClient),
	}
}

func NewClient ( httpClient * http . Client ) * Client { return & Client { client : graphql . NewClient ( " " , httpClient ) , } }

// NewClient creates a new GitHub GraphQL API v4 client with the provided http.Client.
// If httpClient is nil, then http.DefaultClient is used.
//
// Note that GitHub GraphQL API v4 requires authentication, so
// the provided http.Client is expected to take care of that.

NewClient creates a new GitHub GraphQL API v4 client with the provided http . Client . If httpClient is nil then http . DefaultClient is used . Note that GitHub GraphQL API v4 requires authentication so the provided http . Client is expected to take care of that .


func NewEnterpriseClient(url string, httpClient *http.Client) *Client {
	return &Client{
		client: graphql.NewClient(url, httpClient),
	}
}

func NewEnterpriseClient ( url string , httpClient * http . Client ) * Client { return & Client { client : graphql . NewClient ( url , httpClient ) , } }

// NewEnterpriseClient creates a new GitHub GraphQL API v4 client for the GitHub Enterprise
// instance with the specified GraphQL endpoint URL, using the provided http.Client.
// If httpClient is nil, then http.DefaultClient is used.
//
// Note that GitHub GraphQL API v4 requires authentication, so
// the provided http.Client is expected to take care of that.

NewEnterpriseClient creates a new GitHub GraphQL API v4 client for the GitHub Enterprise instance with the specified GraphQL endpoint URL using the provided http . Client . If httpClient is nil then http . DefaultClient is used . Note that GitHub GraphQL API v4 requires authentication so the provided http . Client is expected to take care of that .


func (c *Client) Query(ctx context.Context, q interface{}, variables map[string]interface{}) error {
	return c.client.Query(ctx, q, variables)
}

func ( c * Client ) Query ( ctx context . Context , q interface { } , variables map [ string ] interface { } ) error { return c . client . Query ( ctx , q , variables ) }

// Query executes a single GraphQL query request,
// with a query derived from q, populating the response into it.
// q should be a pointer to struct that corresponds to the GitHub GraphQL schema.

Query executes a single GraphQL query request with a query derived from q populating the response into it . q should be a pointer to struct that corresponds to the GitHub GraphQL schema .


func (c *Client) Mutate(ctx context.Context, m interface{}, input Input, variables map[string]interface{}) error {
	if variables == nil {
		variables = map[string]interface{}{"input": input}
	} else {
		variables["input"] = input
	}
	return c.client.Mutate(ctx, m, variables)
}

func ( c * Client ) Mutate ( ctx context . Context , m interface { } , input Input , variables map [ string ] interface { } ) error { if variables == nil { variables = map [ string ] interface { } { " " : input } } else { variables [ " " ] = input } return c . client . Mutate ( ctx , m , variables ) }

// Mutate executes a single GraphQL mutation request,
// with a mutation derived from m, populating the response into it.
// m should be a pointer to struct that corresponds to the GitHub GraphQL schema.
// Provided input will be set as a variable named "input".

Mutate executes a single GraphQL mutation request with a mutation derived from m populating the response into it . m should be a pointer to struct that corresponds to the GitHub GraphQL schema . Provided input will be set as a variable named input .


func (d *FileSelectDialog) populateFiles() error {
	d.listBox.Clear()
	isRoot := filepath.Dir(d.currPath) == d.currPath

	if !isRoot {
		d.listBox.AddItem("..")
	}

	f, err := os.Open(d.currPath)
	if err != nil {
		return err
	}

	finfos, err := f.Readdir(0)
	f.Close()
	if err != nil {
		return err
	}

	fnLess := func(i, j int) bool {
		if finfos[i].IsDir() && !finfos[j].IsDir() {
			return true
		} else if !finfos[i].IsDir() && finfos[j].IsDir() {
			return false
		}

		return strings.ToLower(finfos[i].Name()) < strings.ToLower(finfos[j].Name())
	}

	sort.Slice(finfos, fnLess)

	for _, finfo := range finfos {
		if !d.fileFitsMask(finfo) {
			continue
		}

		if finfo.IsDir() {
			d.listBox.AddItem(finfo.Name() + string(os.PathSeparator))
		} else {
			d.listBox.AddItem(finfo.Name())
		}
	}

	return nil
}

func ( d * FileSelectDialog ) populateFiles ( ) error { d . listBox . Clear ( ) isRoot := filepath . Dir ( d . currPath ) == d . currPath if ! isRoot { d . listBox . AddItem ( " " ) } f , err := os . Open ( d . currPath ) if err != nil { return err } finfos , err := f . Readdir ( 0 ) f . Close ( ) if err != nil { return err } fnLess := func ( i , j int ) bool { if finfos [ i ] . IsDir ( ) && ! finfos [ j ] . IsDir ( ) { return true } else if ! finfos [ i ] . IsDir ( ) && finfos [ j ] . IsDir ( ) { return false } return strings . ToLower ( finfos [ i ] . Name ( ) ) < strings . ToLower ( finfos [ j ] . Name ( ) ) } sort . Slice ( finfos , fnLess ) for _ , finfo := range finfos { if ! d . fileFitsMask ( finfo ) { continue } if finfo . IsDir ( ) { d . listBox . AddItem ( finfo . Name ( ) + string ( os . PathSeparator ) ) } else { d . listBox . AddItem ( finfo . Name ( ) ) } } return nil }

// Fills the ListBox with the file names from current directory.
// Files which names do not match mask are filtered out.
// If select directory is set, then the ListBox contains only directories.
// Directory names ends with path separator

Fills the ListBox with the file names from current directory . Files which names do not match mask are filtered out . If select directory is set then the ListBox contains only directories . Directory names ends with path separator


func (d *FileSelectDialog) detectPath() {
	p := d.currPath
	if p == "" {
		d.currPath, _ = os.Getwd()
		return
	}

	p = filepath.Clean(p)
	for {
		_, err := os.Stat(p)
		if err == nil {
			break
		}

		dirUp := filepath.Dir(p)
		if dirUp == p {
			p, _ = os.Getwd()
			break
		}

		p = dirUp
	}
	d.currPath = p
}

func ( d * FileSelectDialog ) detectPath ( ) { p := d . currPath if p == " " { d . currPath , _ = os . Getwd ( ) return } p = filepath . Clean ( p ) for { _ , err := os . Stat ( p ) if err == nil { break } dirUp := filepath . Dir ( p ) if dirUp == p { p , _ = os . Getwd ( ) break } p = dirUp } d . currPath = p }

// Tries to find the best fit for the given path.
// It goes up until it gets into the existing directory.
// If all fails it returns working directory.

Tries to find the best fit for the given path . It goes up until it gets into the existing directory . If all fails it returns working directory .


func (d *FileSelectDialog) pathUp() {
	dirUp := filepath.Dir(d.currPath)
	if dirUp == d.currPath {
		return
	}
	d.currPath = dirUp
	d.populateFiles()
	d.selectFirst()
}

func ( d * FileSelectDialog ) pathUp ( ) { dirUp := filepath . Dir ( d . currPath ) if dirUp == d . currPath { return } d . currPath = dirUp d . populateFiles ( ) d . selectFirst ( ) }

// Goes up in the directory tree if it is possible


func (d *FileSelectDialog) pathDown(dir string) {
	d.currPath = filepath.Join(d.currPath, dir)
	d.populateFiles()
	d.selectFirst()
}

func ( d * FileSelectDialog ) pathDown ( dir string ) { d . currPath = filepath . Join ( d . currPath , dir ) d . populateFiles ( ) d . selectFirst ( ) }


func (c *BaseControl) Destroy() {
	c.parent.removeChild(c)
	c.parent.SetConstraints(0, 0)
}

func ( c * BaseControl ) Destroy ( ) { c . parent . removeChild ( c ) c . parent . SetConstraints ( 0 , 0 ) }

// Destroy removes an object from its parental chain


func (d *dbCache) preload(firstRow, rowCount int) {
	if firstRow == d.firstRow && rowCount == d.rowCount {
		// fast path: view area is the same, return immediately
		return
	}

	// slow path: refill cache
	fNames := []string{"Jack", "Alisa", "Richard", "Paul", "Nicole", "Steven", "Jane"}
	lNames := []string{"Smith", "Catcher", "Stone", "White", "Black"}
	posts := []string{"Engineer", "Manager", "Janitor", "Driver"}
	deps := []string{"IT", "Financial", "Support"}
	salary := []int{40000, 38000, 41000, 32000}

	d.data = make([][]string, rowCount, rowCount)
	for i := 0; i < rowCount; i++ {
		absIndex := firstRow + i
		d.data[i] = make([]string, columnInTable, columnInTable)
		d.data[i][0] = fNames[absIndex%len(fNames)]
		d.data[i][1] = lNames[absIndex%len(lNames)]
		d.data[i][2] = fmt.Sprintf("%08d", 100+absIndex)
		d.data[i][3] = posts[absIndex%len(posts)]
		d.data[i][4] = deps[absIndex%len(deps)]
		d.data[i][5] = fmt.Sprintf("%d k/year", salary[absIndex%len(salary)]/1000)
	}

	// do not forget to save the last values
	d.firstRow = firstRow
	d.rowCount = rowCount
}

// cache data from a new row span
// It imitates a random data by selecting values from predefined arrays. Sizes
// of all arrays should be different to make TableView data look more random

cache data from a new row span It imitates a random data by selecting values from predefined arrays . Sizes of all arrays should be different to make TableView data look more random


func (d *dbCache) value(row, col int) string {
	rowId := row - d.firstRow
	if rowId >= len(d.data) {
		return ""
	}
	rowValues := d.data[rowId]
	if col >= len(rowValues) {
		return ""
	}
	return rowValues[col]
}

func ( d * dbCache ) value ( row , col int ) string { rowId := row - d . firstRow if rowId >= len ( d . data ) { return " " } rowValues := d . data [ rowId ] if col >= len ( rowValues ) { return " " } return rowValues [ col ] }

// returns the cell value for a given col and row. Col and row are absolute
// value. But cache keeps limited number of rows to minimize memory usage.
// So, the position of the value of the cell should be calculated
// To simplify, the function just returns empty string if the cell is not
// cached. It is unlikely but can happen

returns the cell value for a given col and row . Col and row are absolute value . But cache keeps limited number of rows to minimize memory usage . So the position of the value of the cell should be calculated To simplify the function just returns empty string if the cell is not cached . It is unlikely but can happen


func RefreshScreen() {
	comp.BeginUpdate()
	term.Clear(ColorWhite, ColorBlack)
	comp.EndUpdate()

	windows := comp.getWindowList()
	for _, wnd := range windows {
		v := wnd.(*Window)
		if v.Visible() {
			wnd.Draw()

			WindowManager().BeginUpdate()
			PushAttributes()
			term.Flush()
			PopAttributes()
			WindowManager().EndUpdate()

		}
	}

	comp.BeginUpdate()
	term.Flush()
	comp.EndUpdate()
}

func RefreshScreen ( ) { comp . BeginUpdate ( ) term . Clear ( ColorWhite , ColorBlack ) comp . EndUpdate ( ) windows := comp . getWindowList ( ) for _ , wnd := range windows { v := wnd . ( * Window ) if v . Visible ( ) { wnd . Draw ( ) WindowManager ( ) . BeginUpdate ( ) PushAttributes ( ) term . Flush ( ) PopAttributes ( ) WindowManager ( ) . EndUpdate ( ) } } comp . BeginUpdate ( ) term . Flush ( ) comp . EndUpdate ( ) }


func AddWindow(posX, posY, width, height int, title string) *Window {
	window := CreateWindow(posX, posY, width, height, title)
	window.SetBorder(comp.windowBorder)

	comp.BeginUpdate()
	comp.windows = append(comp.windows, window)
	comp.EndUpdate()
	window.Draw()
	term.Flush()

	comp.activateWindow(window)

	RefreshScreen()

	return window
}

func AddWindow ( posX , posY , width , height int , title string ) * Window { window := CreateWindow ( posX , posY , width , height , title ) window . SetBorder ( comp . windowBorder ) comp . BeginUpdate ( ) comp . windows = append ( comp . windows , window ) comp . EndUpdate ( ) window . Draw ( ) term . Flush ( ) comp . activateWindow ( window ) RefreshScreen ( ) return window }

// AddWindow constucts a new Window, adds it to the composer automatically,
// and makes it active
// posX and posY are top left coordinates of the Window
// width and height are Window size
// title is a Window title

AddWindow constucts a new Window adds it to the composer automatically and makes it active posX and posY are top left coordinates of the Window width and height are Window size title is a Window title


func (c *Composer) DestroyWindow(view Control) {
	ev := Event{Type: EventClose}
	c.sendEventToActiveWindow(ev)

	windows := c.getWindowList()
	var newOrder []Control
	for i := 0; i < len(windows); i++ {
		if windows[i] != view {
			newOrder = append(newOrder, windows[i])
		}
	}

	if len(newOrder) == 0 {
		go Stop()
		return
	}

	c.BeginUpdate()
	c.windows = newOrder
	c.EndUpdate()
	c.activateWindow(c.topWindow())
}

func ( c * Composer ) DestroyWindow ( view Control ) { ev := Event { Type : EventClose } c . sendEventToActiveWindow ( ev ) windows := c . getWindowList ( ) var newOrder [ ] Control for i := 0 ; i < len ( windows ) ; i ++ { if windows [ i ] != view { newOrder = append ( newOrder , windows [ i ] ) } } if len ( newOrder ) == 0 { go Stop ( ) return } c . BeginUpdate ( ) c . windows = newOrder c . EndUpdate ( ) c . activateWindow ( c . topWindow ( ) ) }

// DestroyWindow removes the Window from the list of managed Windows


func IsDeadKey(key term.Key) bool {
	if key == term.KeyCtrlS || key == term.KeyCtrlP ||
		key == term.KeyCtrlW || key == term.KeyCtrlQ {
		return true
	}

	return false
}

func IsDeadKey ( key term . Key ) bool { if key == term . KeyCtrlS || key == term . KeyCtrlP || key == term . KeyCtrlW || key == term . KeyCtrlQ { return true } return false }

// IsDeadKey returns true if the pressed key is the first key in
// the key sequence understood by composer. Dead key is never sent to
// any control

IsDeadKey returns true if the pressed key is the first key in the key sequence understood by composer . Dead key is never sent to any control


func (l *Label) SetTextDisplay(align Align) {
	if align != AlignLeft && align != AlignRight {
		return
	}

	l.textDisplay = align
}

func ( l * Label ) SetTextDisplay ( align Align ) { if align != AlignLeft && align != AlignRight { return } l . textDisplay = align }

// SetTextDisplay sets which part of the title is displayed in case of the title
// is longer than the lable. Only AlignLeft and AlignRigth are valid values
// for the property. Any other value does is skipped and does not affect
// displaying the title

SetTextDisplay sets which part of the title is displayed in case of the title is longer than the lable . Only AlignLeft and AlignRigth are valid values for the property . Any other value does is skipped and does not affect displaying the title


func CreateRadioGroup() *RadioGroup {
	c := new(RadioGroup)
	c.items = make([]*Radio, 0)
	return c
}

func CreateRadioGroup ( ) * RadioGroup { c := new ( RadioGroup ) c . items = make ( [ ] * Radio , 0 ) return c }

// NewRadioGroup creates a new RadioGroup


func (c *RadioGroup) Selected() int {
	selected := -1

	for id, item := range c.items {
		if item.Selected() {
			selected = id
			break
		}
	}

	return selected
}

func ( c * RadioGroup ) Selected ( ) int { selected := - 1 for id , item := range c . items { if item . Selected ( ) { selected = id break } } return selected }

// Selected returns the number of currently selected radio
// button inside the group or -1 if no button is selected

Selected returns the number of currently selected radio button inside the group or - 1 if no button is selected


func (c *RadioGroup) SelectItem(r *Radio) bool {
	found := false

	for _, item := range c.items {
		if item == r {
			found = true
			item.SetSelected(true)
		} else {
			item.SetSelected(false)
		}
	}

	return found
}

func ( c * RadioGroup ) SelectItem ( r * Radio ) bool { found := false for _ , item := range c . items { if item == r { found = true item . SetSelected ( true ) } else { item . SetSelected ( false ) } } return found }

// SelectItem makes the radio selected. The function returns false
// if it failed to find the radio in the radio group

SelectItem makes the radio selected . The function returns false if it failed to find the radio in the radio group


func (c *RadioGroup) SetSelected(id int) bool {
	found := false
	if id < 0 || id >= len(c.items) {
		return false
	}

	for idx, item := range c.items {
		if idx == id {
			found = true
			item.SetSelected(true)
		} else {
			item.SetSelected(false)
		}
	}

	return found
}

func ( c * RadioGroup ) SetSelected ( id int ) bool { found := false if id < 0 || id >= len ( c . items ) { return false } for idx , item := range c . items { if idx == id { found = true item . SetSelected ( true ) } else { item . SetSelected ( false ) } } return found }

// SetSelected selects the radio by its number. The function
// returns false if the number is invalid for the radio group

SetSelected selects the radio by its number . The function returns false if the number is invalid for the radio group