Package util provides utility functions for the goldmark.
package util

import (
	
	
	
	
	
	
	
	
)
A CopyOnWriteBuffer is a byte buffer that copies buffer when it need to be changed.
NewCopyOnWriteBuffer returns a new CopyOnWriteBuffer.
Write writes given bytes to the buffer. Write allocate new buffer and clears it at the first time.
func ( *CopyOnWriteBuffer) ( []byte) {
	if !.copied {
		.buffer = make([]byte, 0, len(.buffer)+20)
		.copied = true
	}
	.buffer = append(.buffer, ...)
}
WriteString writes given string to the buffer. WriteString allocate new buffer and clears it at the first time.
Append appends given bytes to the buffer. Append copy buffer at the first time.
func ( *CopyOnWriteBuffer) ( []byte) {
	if !.copied {
		 := make([]byte, len(.buffer), len(.buffer)+20)
		copy(, .buffer)
		.buffer = 
		.copied = true
	}
	.buffer = append(.buffer, ...)
}
AppendString appends given string to the buffer. AppendString copy buffer at the first time.
WriteByte writes the given byte to the buffer. WriteByte allocate new buffer and clears it at the first time.
func ( *CopyOnWriteBuffer) ( byte) {
	if !.copied {
		.buffer = make([]byte, 0, len(.buffer)+20)
		.copied = true
	}
	.buffer = append(.buffer, )
}
AppendByte appends given bytes to the buffer. AppendByte copy buffer at the first time.
func ( *CopyOnWriteBuffer) ( byte) {
	if !.copied {
		 := make([]byte, len(.buffer), len(.buffer)+20)
		copy(, .buffer)
		.buffer = 
		.copied = true
	}
	.buffer = append(.buffer, )
}
Bytes returns bytes of this buffer.
func ( *CopyOnWriteBuffer) () []byte {
	return .buffer
}
IsCopied returns true if buffer has been copied, otherwise false.
func ( *CopyOnWriteBuffer) () bool {
	return .copied
}
IsEscapedPunctuation returns true if character at a given index i is an escaped punctuation, otherwise false.
func ( []byte,  int) bool {
	return [] == '\\' &&  < len()-1 && IsPunct([+1])
}
ReadWhile read the given source while pred is true.
func ( []byte,  [2]int,  func(byte) bool) (int, bool) {
	 := [0]
	 := false
	for ;  < [1]; ++ {
		 := []
		if () {
			 = true
			continue
		}
		break
	}
	return , 
}
IsBlank returns true if the given string is all space characters.
func ( []byte) bool {
	for ,  := range  {
		if !IsSpace() {
			return false
		}
	}
	return true
}
VisualizeSpaces visualize invisible space characters.
func ( []byte) []byte {
	 = bytes.Replace(, []byte(" "), []byte("[SPACE]"), -1)
	 = bytes.Replace(, []byte("\t"), []byte("[TAB]"), -1)
	 = bytes.Replace(, []byte("\n"), []byte("[NEWLINE]\n"), -1)
	 = bytes.Replace(, []byte("\r"), []byte("[CR]"), -1)
	return 
}
TabWidth calculates actual width of a tab at the given position.
func ( int) int {
	return 4 - %4
}
IndentPosition searches an indent position with the given width for the given line. If the line contains tab characters, paddings may be not zero. currentPos==0 and width==2: position: 0 1 [TAB]aaaa width: 1234 5678 width=2 is in the tab character. In this case, IndentPosition returns (pos=1, padding=2)
func ( []byte, ,  int) (,  int) {
	if  == 0 {
		return 0, 0
	}
	 := 0
	 := len()
	 := 0
	 := false
	for ;  < ; ++ {
		if [] == '\t' {
			 += TabWidth( + )
			 = true
		} else if [] == ' ' {
			++
		} else {
			break
		}
	}
	if  >=  {
		if ! {
			return , 0
		}
		return ,  - 
	}
	return -1, -1
}
IndentPositionPadding searches an indent position with the given width for the given line. This function is mostly same as IndentPosition except this function takes account into additional paddings.
func ( []byte, , ,  int) (,  int) {
	if  == 0 {
		return 0, 
	}
	 := 0
	 := 0
	 := len()
	for ;  < ; ++ {
		if [] == '\t' {
			 += TabWidth( + )
		} else if [] == ' ' {
			++
		} else {
			break
		}
	}
	if  >=  {
		return  - ,  - 
	}
	return -1, -1
}
DedentPosition dedents lines by the given width.
func ( []byte, ,  int) (,  int) {
	if  == 0 {
		return 0, 0
	}
	 := 0
	 := len()
	 := 0
	for ;  < ; ++ {
		if [] == '\t' {
			 += TabWidth( + )
		} else if [] == ' ' {
			++
		} else {
			break
		}
	}
	if  >=  {
		return ,  - 
	}
	return , 0
}
DedentPositionPadding dedents lines by the given width. This function is mostly same as DedentPosition except this function takes account into additional paddings.
func ( []byte, , ,  int) (,  int) {
	if  == 0 {
		return 0, 
	}

	 := 0
	 := 0
	 := len()
	for ;  < ; ++ {
		if [] == '\t' {
			 += TabWidth( + )
		} else if [] == ' ' {
			++
		} else {
			break
		}
	}
	if  >=  {
		return  - ,  - 
	}
	return  - , 0
}
IndentWidth calculate an indent width for the given line.
func ( []byte,  int) (,  int) {
	 := len()
	for  := 0;  < ; ++ {
		 := []
		if  == ' ' {
			++
			++
		} else if  == '\t' {
			 += TabWidth( + )
			++
		} else {
			break
		}
	}
	return
}
FirstNonSpacePosition returns a position line that is a first nonspace character.
func ( []byte) int {
	 := 0
	for ;  < len(); ++ {
		 := []
		if  == ' ' ||  == '\t' {
			continue
		}
		if  == '\n' {
			return -1
		}
		return 
	}
	return -1
}
FindClosure returns a position that closes the given opener. If codeSpan is set true, it ignores characters in code spans. If allowNesting is set true, closures correspond to nested opener will be ignored.
func ( []byte, ,  byte, ,  bool) int {
	 := 0
	 := 1
	 := 0
	for  < len() {
		 := []
		if  &&  != 0 &&  == '`' {
			 := 0
			for ;  < len(); ++ {
				if [] == '`' {
					++
				} else {
					--
					break
				}
			}
			if  ==  {
				 = 0
			}
		} else if  == 0 &&  == '\\' &&  < len()-1 && IsPunct([+1]) {
			 += 2
			continue
		} else if  &&  == 0 &&  == '`' {
			for ;  < len(); ++ {
				if [] == '`' {
					++
				} else {
					--
					break
				}
			}
		} else if ( &&  == 0) || ! {
			if  ==  {
				--
				if  == 0 {
					return 
				}
			} else if  ==  {
				if ! {
					return -1
				}
				++
			}
		}
		++
	}
	return -1
}
TrimLeft trims characters in the given s from head of the source. bytes.TrimLeft offers same functionalities, but bytes.TrimLeft allocates new buffer for the result.
func (,  []byte) []byte {
	 := 0
	for ;  < len(); ++ {
		 := []
		 := false
		for  := 0;  < len(); ++ {
			if  == [] {
				 = true
				break
			}
		}
		if ! {
			break
		}
	}
	return [:]
}
TrimRight trims characters in the given s from tail of the source.
func (,  []byte) []byte {
	 := len() - 1
	for ;  >= 0; -- {
		 := []
		 := false
		for  := 0;  < len(); ++ {
			if  == [] {
				 = true
				break
			}
		}
		if ! {
			break
		}
	}
	return [:+1]
}
TrimLeftLength returns a length of leading specified characters.
func (,  []byte) int {
	return len() - len(TrimLeft(, ))
}
TrimRightLength returns a length of trailing specified characters.
func (,  []byte) int {
	return len() - len(TrimRight(, ))
}
TrimLeftSpaceLength returns a length of leading space characters.
func ( []byte) int {
	 := 0
	for ;  < len(); ++ {
		if !IsSpace([]) {
			break
		}
	}
	return 
}
TrimRightSpaceLength returns a length of trailing space characters.
func ( []byte) int {
	 := len()
	 :=  - 1
	for ;  >= 0; -- {
		if !IsSpace([]) {
			break
		}
	}
	if  < 0 {
		return 
	}
	return  - 1 - 
}
TrimLeftSpace returns a subslice of the given string by slicing off all leading space characters.
func ( []byte) []byte {
	return TrimLeft(, spaces)
}
TrimRightSpace returns a subslice of the given string by slicing off all trailing space characters.
func ( []byte) []byte {
	return TrimRight(, spaces)
}
DoFullUnicodeCaseFolding performs full unicode case folding to given bytes.
func ( []byte) []byte {
	var  []byte
	 := NewCopyOnWriteBuffer()
	 := 0
	for  := 0;  < len(); ++ {
		 := []
		if  < 0xb5 {
A-Z to a-z
				.Write([:])
				.WriteByte( + 32)
				 =  + 1
			}
			continue
		}

		if !utf8.RuneStart() {
			continue
		}
		,  := utf8.DecodeRune([:])
		if  == utf8.RuneError {
			continue
		}
		,  := unicodeCaseFoldings[]
		if ! {
			continue
		}

		.Write([:])
		if  == nil {
			 = make([]byte, 4)
		}
		for ,  := range  {
			 := utf8.EncodeRune(, )
			.Write([:])
		}
		 +=  - 1
		 =  + 1
	}
	if .IsCopied() {
		.Write([:])
	}
	return .Bytes()
}
ReplaceSpaces replaces sequence of spaces with the given repl.
func ( []byte,  byte) []byte {
	var  []byte
	 := -1
	for ,  := range  {
		 := IsSpace()
		if  < 0 &&  {
			 = 
			continue
		} else if  >= 0 &&  {
			continue
		} else if  >= 0 {
			if  == nil {
				 = make([]byte, 0, len())
				 = append(, [:]...)
			}
			 = append(, )
			 = -1
		}
		if  != nil {
			 = append(, )
		}
	}
	if  >= 0 &&  != nil {
		 = append(, )
	}
	if  == nil {
		return 
	}
	return 
}
ToRune decode given bytes start at pos and returns a rune.
func ( []byte,  int) rune {
	 := 
	for ;  >= 0; -- {
		if utf8.RuneStart([]) {
			break
		}
	}
	,  := utf8.DecodeRune([:])
	return 
}
ToValidRune returns 0xFFFD if the given rune is invalid, otherwise v.
func ( rune) rune {
	if  == 0 || !utf8.ValidRune() {
		return rune(0xFFFD)
	}
	return 
}
ToLinkReference converts given bytes into a valid link reference string. ToLinkReference performs unicode case folding, trims leading and trailing spaces, converts into lower case and replace spaces with a single space character.
func ( []byte) string {
	 = TrimLeftSpace()
	 = TrimRightSpace()
	 = DoFullUnicodeCaseFolding()
	return string(ReplaceSpaces(, ' '))
}

var htmlEscapeTable = [256][]byte{nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []byte("&quot;"), nil, nil, nil, []byte("&amp;"), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []byte("&lt;"), nil, []byte("&gt;"), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil}
EscapeHTMLByte returns HTML escaped bytes if the given byte should be escaped, otherwise nil.
func ( byte) []byte {
	return htmlEscapeTable[]
}
EscapeHTML escapes characters that should be escaped in HTML text.
func ( []byte) []byte {
	 := NewCopyOnWriteBuffer()
	 := 0
	for  := 0;  < len(); ++ {
		 := []
		 := htmlEscapeTable[]
		if  != nil {
			.Write([:])
			.Write()
			 =  + 1
		}
	}
	if .IsCopied() {
		.Write([:])
	}
	return .Bytes()
}
UnescapePunctuations unescapes blackslash escaped punctuations.
func ( []byte) []byte {
	 := NewCopyOnWriteBuffer()
	 := len()
	 := 0
	for  := 0;  < ; {
		 := []
		if  < -1 &&  == '\\' && IsPunct([+1]) {
			.Write([:])
			.WriteByte([+1])
			 += 2
			 = 
			continue
		}
		++
	}
	if .IsCopied() {
		.Write([:])
	}
	return .Bytes()
}
ResolveNumericReferences resolve numeric references like '&#1234;" .
func ( []byte) []byte {
	 := NewCopyOnWriteBuffer()
	 := make([]byte, 6, 6)
	 := len()
	 := false
	 := 0
	for  := 0;  < ; ++ {
		if [] == '&' {
			 := 
			 :=  + 1
			if  <  && [] == '#' {
				 :=  + 1
				if  <  {
code point like #x22;
					if  <  &&  == 'x' ||  == 'X' {
						 :=  + 1
						,  = ReadWhile(, [2]int{, }, IsHexDecimal)
						if  &&  <  && [] == ';' {
							,  := strconv.ParseUint(BytesToReadOnlyString([:]), 16, 32)
							.Write([:])
							 =  + 1
							 := utf8.EncodeRune(, ToValidRune(rune()))
							.Write([:])
							continue
code point like #1234;
					} else if  >= '0' &&  <= '9' {
						 := 
						,  = ReadWhile(, [2]int{, }, IsNumeric)
						if  &&  <  && - < 8 && [] == ';' {
							,  := strconv.ParseUint(BytesToReadOnlyString([:]), 0, 32)
							.Write([:])
							 =  + 1
							 := utf8.EncodeRune(, ToValidRune(rune()))
							.Write([:])
							continue
						}
					}
				}
			}
			 =  - 1
		}
	}
	if .IsCopied() {
		.Write([:])
	}
	return .Bytes()
}
ResolveEntityNames resolve entity references like '&ouml;" .
func ( []byte) []byte {
	 := NewCopyOnWriteBuffer()
	 := len()
	 := false
	 := 0
	for  := 0;  < ; ++ {
		if [] == '&' {
			 := 
			 :=  + 1
			if !( <  && [] == '#') {
				 := 
				,  = ReadWhile(, [2]int{, }, IsAlphaNumeric)
				if  &&  <  && [] == ';' {
					 := BytesToReadOnlyString([:])
					,  := LookUpHTML5EntityByName()
					if  {
						.Write([:])
						 =  + 1
						.Write(.Characters)
						continue
					}
				}
			}
			 =  - 1
		}
	}
	if .IsCopied() {
		.Write([:])
	}
	return .Bytes()
}

var htmlSpace = []byte("%20")
URLEscape escape the given URL. If resolveReference is set true: 1. unescape punctuations 2. resolve numeric references 3. resolve entity references URL encoded values (%xx) are kept as is.
func ( []byte,  bool) []byte {
	if  {
		 = UnescapePunctuations()
		 = ResolveNumericReferences()
		 = ResolveEntityNames()
	}
	 := NewCopyOnWriteBuffer()
	 := len()
	 := 0

	for  := 0;  < ; {
		 := []
		if urlEscapeTable[] == 1 {
			++
			continue
		}
		if  == '%' && +2 <  && IsHexDecimal([+1]) && IsHexDecimal([+1]) {
			 += 3
			continue
		}
		 := utf8lenTable[]
		if  == 99 { // invalid utf8 leading byte, skip it
			++
			continue
		}
		if  == ' ' {
			.Write([:])
			.Write(htmlSpace)
			++
			 = 
			continue
		}
		if int() >= len() {
			 = int8(len() - 1)
		}
		if  == 0 {
			++
			 = 
			continue
		}
		.Write([:])
		 :=  + int()
		if  > len() {
			++
			 = 
			continue
		}
		.Write(StringToReadOnlyBytes(url.QueryEscape(string([:]))))
		 += int()
		 = 
	}
	if .IsCopied() &&  <  {
		.Write([:])
	}
	return .Bytes()
}
FindURLIndex returns a stop index value if the given bytes seem an URL. This function is equivalent to [A-Za-z][A-Za-z0-9.+-]{1,31}:[^<>\x00-\x20]* .
func ( []byte) int {
	 := 0
	if !(len() > 0 && urlTable[[]]&7 == 7) {
		return -1
	}
	++
	for ;  < len(); ++ {
		 := []
		if urlTable[]&4 != 4 {
			break
		}
	}
	if  == 1 ||  > 33 ||  >= len() {
		return -1
	}
	if [] != ':' {
		return -1
	}
	++
	for ;  < len(); ++ {
		 := []
		if urlTable[]&1 != 1 {
			break
		}
	}
	return 
}

var emailDomainRegexp = regexp.MustCompile(`^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*`)
FindEmailIndex returns a stop index value if the given bytes seem an email address.
TODO: eliminate regexps
	 := 0
	for ;  < len(); ++ {
		 := []
		if emailTable[]&1 != 1 {
			break
		}
	}
	if  == 0 {
		return -1
	}
	if  >= len() || [] != '@' {
		return -1
	}
	++
	if  >= len() {
		return -1
	}
	 := emailDomainRegexp.FindSubmatchIndex([:])
	if  == nil {
		return -1
	}
	return  + [1]
}

var spaces = []byte(" \t\n\x0b\x0c\x0d")

var spaceTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

var punctTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
a-zA-Z0-9, ;/?:@&=+$,-_.!~*'()#
var urlEscapeTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

var utf8lenTable = [256]int8{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 99, 99, 99, 99, 99, 99, 99, 99}

var urlTable = [256]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 5, 5, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 0, 1, 0, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}

var emailTable = [256]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
UTF8Len returns a byte length of the utf-8 character.
func ( byte) int8 {
	return utf8lenTable[]
}
IsPunct returns true if the given character is a punctuation, otherwise false.
func ( byte) bool {
	return punctTable[] == 1
}
IsPunctRune returns true if the given rune is a punctuation, otherwise false.
func ( rune) bool {
	return int32() <= 256 && IsPunct(byte()) || unicode.IsPunct()
}
IsSpace returns true if the given character is a space, otherwise false.
func ( byte) bool {
	return spaceTable[] == 1
}
IsSpaceRune returns true if the given rune is a space, otherwise false.
func ( rune) bool {
	return int32() <= 256 && IsSpace(byte()) || unicode.IsSpace()
}
IsNumeric returns true if the given character is a numeric, otherwise false.
func ( byte) bool {
	return  >= '0' &&  <= '9'
}
IsHexDecimal returns true if the given character is a hexdecimal, otherwise false.
func ( byte) bool {
	return  >= '0' &&  <= '9' ||  >= 'a' &&  <= 'f' ||  >= 'A' &&  <= 'F'
}
IsAlphaNumeric returns true if the given character is a alphabet or a numeric, otherwise false.
func ( byte) bool {
	return  >= 'a' &&  <= 'z' ||  >= 'A' &&  <= 'Z' ||  >= '0' &&  <= '9'
}
A BufWriter is a subset of the bufio.Writer .
type BufWriter interface {
	io.Writer
	Available() int
	Buffered() int
	Flush() error
	WriteByte(c byte) error
	WriteRune(r rune) (size int, err error)
	WriteString(s string) (int, error)
}
A PrioritizedValue struct holds pair of an arbitrary value and a priority.
Value is an arbitrary value that you want to prioritize.
Priority is a priority of the value.
PrioritizedSlice is a slice of the PrioritizedValues
Sort sorts the PrioritizedSlice in ascending order.
func ( PrioritizedSlice) () {
	sort.Slice(, func(,  int) bool {
		return [].Priority < [].Priority
	})
}
Remove removes the given value from this slice.
func ( PrioritizedSlice) ( interface{}) PrioritizedSlice {
	 := 0
	 := false
	for ;  < len(); ++ {
		if [].Value ==  {
			 = true
			break
		}
	}
	if ! {
		return 
	}
	return append([:], [+1:]...)
}
Prioritized returns a new PrioritizedValue.
func ( interface{},  int) PrioritizedValue {
	return PrioritizedValue{, }
}

func ( []byte) uint64 {
	var  uint64 = 5381
	for ,  := range  {
		 = (( << 5) + ) + uint64()
	}
	return 
}
BytesFilter is a efficient data structure for checking whether bytes exist or not. BytesFilter is thread-safe.
Add adds given bytes to this set.
	Add([]byte)
Contains return true if this set contains given bytes, otherwise false.
	Contains([]byte) bool
Extend copies this filter and adds given bytes to new filter.
	Extend(...[]byte) BytesFilter
}

type bytesFilter struct {
	chars     [256]uint8
	threshold int
	slots     [][][]byte
}
NewBytesFilter returns a new BytesFilter.
func ( ...[]byte) BytesFilter {
	 := &bytesFilter{
		threshold: 3,
		slots:     make([][][]byte, 64),
	}
	for ,  := range  {
		.Add()
	}
	return 
}

func ( *bytesFilter) ( []byte) {
	 := len()
	 := .threshold
	if  < .threshold {
		 = 
	}
	for  := 0;  < ; ++ {
		.chars[[]] |= 1 << uint8()
	}
	 := bytesHash() % uint64(len(.slots))
	 := .slots[]
	if  == nil {
		 = [][]byte{}
	}
	.slots[] = append(, )
}

func ( *bytesFilter) ( ...[]byte) BytesFilter {
	 := NewBytesFilter().(*bytesFilter)
	.chars = .chars
	.threshold = .threshold
	for ,  := range .slots {
		 := make([][]byte, len())
		copy(, )
		.slots[] = 
	}
	for ,  := range  {
		.Add()
	}
	return 
}

func ( *bytesFilter) ( []byte) bool {
	 := len()
	 := .threshold
	if  < .threshold {
		 = 
	}
	for  := 0;  < ; ++ {
		if (.chars[[]] & (1 << uint8())) == 0 {
			return false
		}
	}
	 := bytesHash() % uint64(len(.slots))
	 := .slots[]
	if  == nil || len() == 0 {
		return false
	}
	for ,  := range  {
		if bytes.Equal(, ) {
			return true
		}
	}
	return false