<commit_before>package browscap_go

import (
	"fmt"
	"reflect"
	"strings"
)

type Browser struct {
	built  bool   // has complete data from parents
	parent string //name of the parent

	Browser         string
	BrowserVersion  string
	BrowserMajorVer string
	BrowserMinorVer string
	// Browser, Application, Bot/Crawler, Useragent Anonymizer, Offline Browser,
	// Multimedia Player, Library, Feed Reader, Email Client or unknown
	BrowserType string

	Platform        string
	PlatformShort   string
	PlatformVersion string

	// Mobile Phone, Mobile Device, Tablet, Desktop, TV Device, Console,
	// FonePad, Ebook Reader, Car Entertainment System or unknown
	DeviceType  string
	DeviceName  string
	DeviceBrand string
}

func (browser *Browser) build(browsers map[string]*Browser) {
	if browser.built {
		return
	}

	n := reflect.ValueOf(*browser).NumField()

	current := reflect.ValueOf(browser)
	parent := browser.parent
	for parent != "" {
		b, ok := browsers[parent]
		if !ok {
			break
		}

		parentObj := reflect.ValueOf(b)
		for i := 0; i < n; i++ {
			cField := current.Elem().Field(i)
			if cField.String() != "" {
				continue
			}

			pField := parentObj.Elem().Field(i)
			if pField.String() == "" {
				continue
			}

			cField.SetString(pField.String())
		}

		parent = b.parent
	}

	browser.built = true
}

func (browser *Browser) setValue(key, item string) {
	if key == "Parent" {
		browser.parent = item
	} else if key == "Browser" {
		browser.Browser = item
	} else if key == "Version" {
		browser.BrowserVersion = item
	} else if key == "MajorVer" {
		browser.BrowserMajorVer = item
	} else if key == "MinorVer" {
		browser.BrowserMinorVer = item
	} else if key == "Browser_Type" {
		browser.BrowserType = item
	} else if key == "Platform" {
		browser.Platform = item
		browser.PlatformShort = strings.ToLower(item)

		if strings.HasPrefix(browser.PlatformShort, "win") {
			browser.PlatformShort = "win"
		} else if strings.HasPrefix(browser.PlatformShort, "mac") {
			browser.PlatformShort = "mac"
		}
	} else if key == "Platform_Version" {
		browser.PlatformVersion = item
	} else if key == "Device_Type" {
		browser.DeviceType = item
	} else if key == "Device_Code_Name" {
		browser.DeviceName = item
	} else if key == "Device_Brand_Name" {
		browser.DeviceBrand = item
	}
}

func extractBrowser(data map[string]string) *Browser {
	browser := &Browser{}

	if debug {
		fmt.Println("= Browser ==================")<commit_msg>New browser attributes<commit_after>package browscap_go

import (
	"fmt"
	"reflect"
	"strings"
	"sync"
)

type Browser struct {
	built   bool // has complete data from parents
	buildMu sync.Mutex
	parent  string //name of the parent

	Browser         string
	BrowserVersion  string
	BrowserMajorVer string
	BrowserMinorVer string
	// Browser, Application, Bot/Crawler, Useragent Anonymizer, Offline Browser,
	// Multimedia Player, Library, Feed Reader, Email Client or unknown
	BrowserType string

	Platform        string
	PlatformShort   string
	PlatformVersion string

	// Mobile Phone, Mobile Device, Tablet, Desktop, TV Device, Console,
	// FonePad, Ebook Reader, Car Entertainment System or unknown
	DeviceType  string
	DeviceName  string
	DeviceBrand string

	Crawler string

	Cookies    string
	JavaScript string

	RenderingEngineName    string
	RenderingEngineVersion string
}

func (browser *Browser) build(browsers map[string]*Browser) {
	if browser.built {
		return
	}

	browser.buildMu.Lock()
	defer browser.buildMu.Unlock()
	if browser.built {
		return
	}

	n := reflect.ValueOf(*browser).NumField()

	current := reflect.ValueOf(browser)
	parent := browser.parent
	for parent != "" {
		b, ok := browsers[parent]
		if !ok {
			break
		}

		parentObj := reflect.ValueOf(b)
		for i := 0; i < n; i++ {
			cField := current.Elem().Field(i)
			if cField.String() != "" {
				continue
			}

			pField := parentObj.Elem().Field(i)
			if pField.String() == "" {
				continue
			}

			cField.SetString(pField.String())
		}

		parent = b.parent
	}

	browser.built = true
}

func (browser *Browser) setValue(key, item string) {
	if key == "Parent" {
		browser.parent = item
	} else if key == "Browser" {
		browser.Browser = item
	} else if key == "Version" {
		browser.BrowserVersion = item
	} else if key == "MajorVer" {
		browser.BrowserMajorVer = item
	} else if key == "MinorVer" {
		browser.BrowserMinorVer = item
	} else if key == "Browser_Type" {
		browser.BrowserType = item
	} else if key == "JavaScript" {
		browser.JavaScript = item
	} else if key == "Cookies" {
		browser.Cookies = item
	} else if key == "Crawler" {
		browser.Crawler = item
	} else if key == "Platform" {
		browser.Platform = item
		browser.PlatformShort = strings.ToLower(item)

		if strings.HasPrefix(browser.PlatformShort, "win") {
			browser.PlatformShort = "win"
		} else if strings.HasPrefix(browser.PlatformShort, "mac") {
			browser.PlatformShort = "mac"
		}
	} else if key == "Platform_Version" {
		browser.PlatformVersion = item
	} else if key == "RenderingEngine_Name" {
		browser.RenderingEngineName = item
	} else if key == "RenderingEngine_Version" {
		browser.RenderingEngineVersion = item
	} else if key == "Device_Type" {
		browser.DeviceType = item
	} else if key == "Device_Code_Name" {
		browser.DeviceName = item
	} else if key == "Device_Brand_Name" {
		browser.DeviceBrand = item
	}
}

func extractBrowser(data map[string]string) *Browser {
	browser := &Browser{}

	if debug {
		fmt.Println("= Browser ==================")
{'fraction_non_alphanumeric': 0.12212065813528336, 'fraction_numerical': 0.00036563071297989033, 'mean_word_length': 3.6325148179508893, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6554453', 'n_tokens_mistral': 1906, 'n_tokens_neox': 1738, 'n_words': 483}