diff --git a/.dockerignore b/.dockerignore index aec92e5..e69de29 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +0,0 @@ -cmd/agent-ui/output -cmd/agent-ui/bind_* diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 300f1b2..e519dfc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,8 +66,6 @@ jobs: echo "::set-output name=format_ok::1" fi - cd cmd/agent-ui && ./placeholders.sh && cd ../.. - echo "Starting vault" vault server -dev & echo $! > $HOME/vault.pid echo "Waiting vault settle" & sleep 2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2b2088e..88555a7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,8 +60,6 @@ jobs: echo "::set-output name=format_ok::1" fi - cd cmd/agent-ui && ./placeholders.sh && cd ../.. - echo "Starting vault" vault server -dev & echo $! > $HOME/vault.pid echo "Waiting vault settle" & sleep 2 @@ -123,9 +121,6 @@ jobs: run: | export COMMIT=${GITHUB_SHA::8} export GO111MODULE=on - cd cmd/agent-ui - "./placeholders.sh" - cd ../.. echo "Calling travis-binary-build.sh" "./scripts/travis-binary-build.sh" echo "Done" diff --git a/.travis.yml b/.travis.yml index 15a9908..019f974 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,10 +9,6 @@ go: - 1.13.x git: depth: 1 -before_install: -- cd cmd/agent-ui -- "./placeholders.sh" -- cd ../.. script: - echo "Calling travis-binary-build.sh" - "./scripts/travis-binary-build.sh" diff --git a/README.md b/README.md index 793386a..ddeade7 100644 --- a/README.md +++ b/README.md @@ -69,17 +69,7 @@ These are the Environment Variables that you can set to manage the webserver: * `RequestIDHeader` => Header field to get request ID * `LOG_FORMAT` => Change log format (default is pipe delimited, provide the value `json` to log in JSON format) -Agent UI Development -==================== +Where is AgentUI?? +================== -The graphql-playground fork for AgentUI is hosted at [https://github.com/quan-to/graphql-playground](https://github.com/quan-to/graphql-playground) - -Top update agent-ui playground: - -1. Clone Repository https://github.com/quan-to/graphql-playground -2. `yarn` -3. Edit the package `packages/graphql-playground-react` -4. `yarn build` -5. Copy `build/*` to `cmd/agent-ui/resources/app/` -6. Change `/static/` to `./static/` in `cmd/agent-ui/resources/app/index.html` -7. Run `astilectron-bundler` in `cmd/agent-ui` +Agent-UI project has been moved to a separated repository. Check [https://github.com/quan-to/agent-ui](https://github.com/quan-to/agent-ui) \ No newline at end of file diff --git a/cmd/agent-ui/.gitignore b/cmd/agent-ui/.gitignore deleted file mode 100644 index b7d7b2d..0000000 --- a/cmd/agent-ui/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -output -store -bind_*.go -keys diff --git a/cmd/agent-ui/agentui.go b/cmd/agent-ui/agentui.go deleted file mode 100644 index 91c1ed1..0000000 --- a/cmd/agent-ui/agentui.go +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import ( - "flag" - "github.com/asticode/go-astilectron" - "github.com/quan-to/chevron/internal/tools" - "github.com/quan-to/slog" -) - -// Vars -var ( - AppName string - BuiltAt string - debug = flag.Bool("d", false, "enables the debug mode") - w *astilectron.Window - log = slog.Scope("AgentUI").Tag(tools.DefaultTag) -) - -func main() { - // Init - flag.Parse() - slog.SetDebug(*debug) - - Migrate() - - // Run bootstrap - log.Debug("Running app built at %s", BuiltAt) - Begin() - Run() -} diff --git a/cmd/agent-ui/bind.go b/cmd/agent-ui/bind.go deleted file mode 100644 index b72874d..0000000 --- a/cmd/agent-ui/bind.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build !linux,amd64 -// +build !darwin,amd64 -// +build !windows,amd64 - -// Placeholder file for assets binding -package main - -func Asset(name string) ([]byte, error) { - return []byte{}, nil -} - -func AssetDir(name string) ([]string, error) { - return []string{}, nil -} - -func RestoreAssets(dir, name string) error { - return nil -} diff --git a/cmd/agent-ui/bundleit.sh b/cmd/agent-ui/bundleit.sh deleted file mode 100755 index f535ba4..0000000 --- a/cmd/agent-ui/bundleit.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -cat << EOF > bind.go -// +build !linux,amd64 -// +build !darwin,amd64 -// +build !windows,amd64 - -// Placeholder file for assets binding -package main - -func Asset(name string) ([]byte, error) { - return []byte{}, nil -} - -func AssetDir(name string) ([]string, error) { - return []string{}, nil -} - -func RestoreAssets(dir, name string) error { - return nil -} -EOF - -astilectron-bundler -d -w -l diff --git a/cmd/agent-ui/bundler.json b/cmd/agent-ui/bundler.json deleted file mode 100644 index 37bb517..0000000 --- a/cmd/agent-ui/bundler.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "app_name": "AgentUI", - "icon_path_darwin": "resources/icon.icns", - "icon_path_linux": "resources/icon.png", - "icon_path_windows": "resources/icon.ico", - "environments": [ - {"arch": "amd64", "os": "darwin"}, - {"arch": "amd64", "os": "linux"}, - {"arch": "amd64", "os": "windows"} - ], - "version_electron": "7.1.10", - "version_astilectron": "0.37.0" -} diff --git a/cmd/agent-ui/handleMessages.go b/cmd/agent-ui/handleMessages.go deleted file mode 100644 index 57d97ec..0000000 --- a/cmd/agent-ui/handleMessages.go +++ /dev/null @@ -1,133 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "github.com/asticode/go-astilectron" - "github.com/asticode/go-astilectron-bootstrap" - "github.com/quan-to/slog" - "strings" -) - -const ( - messageError = "error" - messageLog = "log" - messageSign = "sign" - messageEncrypt = "encrypt" - messageDecrypt = "decrypt" - messageAddPrivateKey = "addPrivateKey" - messageUnlockKey = "unlockKey" - messageListPrivateKeys = "listKeys" - messageLoadPrivateKey = "loadPrivateKey" - messageLoadPrivateKeyResult = "loadPrivateKeyResult" -) - -var electronLog = slog.Scope("Electron") - -// handleMessages handles messages -func handleMessages(_ *astilectron.Window, m bootstrap.MessageIn) (payload interface{}, err error) { - log.DebugNote("Received message %s", m.Name) - switch m.Name { - case messageLoadPrivateKey: - var paths []string - if err = json.Unmarshal(m.Payload, &paths); err != nil { - payload = err.Error() - return - } - log.Info("Loading keys from %s", strings.Join(paths, ", ")) - hasErrors, errs := AddKeys(paths) - if hasErrors { - for i, v := range errs { - if v != "" { - log.Error("Error processing key %d (%s): %s", i, paths[i], v) - } - } - _ = w.SendMessage(bootstrap.MessageOut{ - Name: messageError, - Payload: errs, - }) - return errs, fmt.Errorf("one or more keys cannot be loaded") - } - _ = w.SendMessage(bootstrap.MessageOut{ - Name: messageLoadPrivateKeyResult, - Payload: "OK", - }) - return "OK", nil - case messageListPrivateKeys: - return ListPrivateKeys() - case messageSign: - var p map[string]interface{} - if err = json.Unmarshal(m.Payload, &p); err != nil { - payload = err.Error() - return - } - - fingerPrint := p["fingerPrint"] - data := p["data"] - - if fingerPrint == nil || data == nil { - err = fmt.Errorf("fingerPrint or data missing") - return - } - - return Sign(fingerPrint.(string), data.(string)) - case messageEncrypt: - return nil, fmt.Errorf("not implemented") - case messageDecrypt: - return nil, fmt.Errorf("not implemented") - case messageAddPrivateKey: - key := string(m.Payload) - return AddPrivateKey(key) - case messageUnlockKey: - var p map[string]interface{} - if err = json.Unmarshal(m.Payload, &p); err != nil { - payload = err.Error() - return - } - - fingerPrint := p["fingerPrint"] - password := p["password"] - - if fingerPrint == nil || password == nil { - err = fmt.Errorf("fingerPrint or password missing") - return - } - - return UnlockKey(fingerPrint.(string), password.(string)) - case messageLog: - var arguments map[int]interface{} - if err = json.Unmarshal(m.Payload, &arguments); err != nil { - payload = err.Error() - return - } - args := make([]interface{}, len(arguments)) - fStr := "" - - i := 0 - for _, v := range arguments { - args[i] = v - switch v.(type) { - case string: - fStr += "%s " - case int: - fStr += "%d " - case float32: - fStr += "%f " - case float64: - fStr += "%f " - case map[string]interface{}: - newV, _ := json.Marshal(v) - args[i] = string(newV) - fStr += "%s" - default: - fStr += "%+v" - } - fStr += " " - i++ - } - electronLog.Info(fStr, args...) - default: - log.Error("Unknown Message: %+v", m) - } - return -} diff --git a/cmd/agent-ui/localResources.go b/cmd/agent-ui/localResources.go deleted file mode 100644 index 44beb92..0000000 --- a/cmd/agent-ui/localResources.go +++ /dev/null @@ -1,195 +0,0 @@ -package main - -import ( - "context" - "crypto" - "fmt" - "github.com/quan-to/chevron/pkg/chevronlib" - "github.com/quan-to/chevron/pkg/interfaces" - "github.com/quan-to/chevron/pkg/models" - "io/ioutil" - "net/http" - "os" - "path" - "path/filepath" - "strings" -) - -const ( - MaxFileSize = 2 * 1024 * 1024 // 1MB -) - -var ( - pgp interfaces.PGPManager - krm interfaces.KeyRingManager - executableFolder string - keysFolder string -) - -var ctx = context.Background() - -func init() { - ex, _ := os.Executable() - executableFolder = filepath.Dir(ex) - keysFolder = path.Join(executableFolder, "keys") -} - -func Begin() { - _ = os.Mkdir(keysFolder, os.ModePerm) - kb := chevronlib.MakeSaveToDiskBackend(nil, keysFolder, "key_") - krm = chevronlib.MakeKeyRingManager(nil) - pgp = chevronlib.MakePGPManager(nil, kb, krm) - pgp.LoadKeys(ctx) -} - -func AddPrivateKey(privateKeyData string) (string, error) { - n, err := pgp.LoadKey(ctx, privateKeyData) - if err != nil { - return err.Error(), err - } - - return fmt.Sprintf("Loaded %d keys", n), nil -} - -func UnlockKey(fingerPrint, password string) (string, error) { - err := pgp.UnlockKey(ctx, fingerPrint, password) - if err != nil { - log.Error("Error unlocking key %s: %s", fingerPrint, err) - return err.Error(), err - } - - return fmt.Sprintf("Key %s unlocked!", fingerPrint), nil -} - -func Sign(fingerPrint, data string) (string, error) { - key := pgp.GetPrivateKeyInfo(ctx, fingerPrint) - - if key == nil { - err := fmt.Errorf("key not found") - return err.Error(), err - } - - if !key.PrivateKeyIsDecrypted { - err := fmt.Errorf("key is not decrypted") - return err.Error(), err - } - - signature, err := pgp.SignData(ctx, fingerPrint, []byte(data), crypto.SHA512) - if err != nil { - return err.Error(), err - } - quantoSig := chevronlib.GPG2Quanto(signature, fingerPrint, "SHA512") - return quantoSig, nil -} - -func ListPrivateKeys() ([]models.KeyInfo, error) { - return pgp.GetLoadedPrivateKeys(ctx), nil -} - -func IsFile(name string) bool { - fi, err := os.Stat(name) - if err != nil { - return false - } - - return fi.Mode().IsRegular() -} - -func FileSize(name string) int64 { - fi, err := os.Stat(name) - if err != nil { - return 0 - } - - return fi.Size() -} - -func GetFileContentType(name string) string { - f, err := os.Open(name) - if err != nil { - panic(err) - } - defer f.Close() - - // Only the first 512 bytes are used to sniff the content type. - buffer := make([]byte, 512) - - _, err = f.Read(buffer) - if err != nil { - return "error reading file" - } - - // Use the net/http package's handy DectectContentType function. Always returns a valid - // content-type by returning "application/octet-stream" if no others seemed to match. - contentType := http.DetectContentType(buffer) - - return contentType -} - -func AddKeys(files []string) (bool, []string) { - errors := make([]string, len(files)) - hasErrors := false - - for i, file := range files { - if !IsFile(file) { - errors[i] = fmt.Sprintf("%s is not a regular file", file) - hasErrors = true - continue - } - - fileType := GetFileContentType(file) - if !strings.Contains(fileType, "text/plain") { - errors[i] = fmt.Sprintf("invalid file type: %s", fileType) - hasErrors = true - continue - } - - size := FileSize(file) - if size > MaxFileSize { - errors[i] = fmt.Sprintf("file size too big: %d", size) - hasErrors = true - continue - } - - data, err := ioutil.ReadFile(file) - if err != nil { - errors[i] = err.Error() - hasErrors = true - continue - } - - fingerPrint, err := chevronlib.GetFingerprintFromKey(string(data)) - if err != nil { - errors[i] = err.Error() - continue - } - - log.Info("Saving key %s from %s", fingerPrint, file) - err = pgp.SaveKey(fingerPrint, string(data), nil) - if err != nil { - errors[i] = err.Error() - hasErrors = true - continue - } - - pgp.LoadKeys(ctx) - } - - return hasErrors, errors -} - -func Migrate() { - storeFolder := path.Join(executableFolder, "store") - if chevronlib.FolderExists(storeFolder) { // Old key store - log.Warn("Found \"store\" folder. Migrating keys...") - err := chevronlib.CopyFiles(storeFolder, keysFolder) - if err != nil { - log.Error("Error moving files from store to keys: %s", err) - } else { - err = os.RemoveAll(storeFolder) - if err != nil { - log.Error("Error removing folder store: %s", err) - } - } - } -} diff --git a/cmd/agent-ui/placeholders.sh b/cmd/agent-ui/placeholders.sh deleted file mode 100755 index 2c4ffe1..0000000 --- a/cmd/agent-ui/placeholders.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash - -cat << EOF > bind_darwin_amd64.go -// +build darwin,amd64 - -// Placeholder file for assets binding -package main - -func Asset(name string) ([]byte, error) { - return []byte{}, nil -} - -func AssetDir(name string) ([]string, error) { - return []string{}, nil -} - -func RestoreAssets(dir, name string) error { - return nil -} -EOF -cat << EOF > bind_linux_amd64.go -// +build linux,amd64 - -// Placeholder file for assets binding -package main - -func Asset(name string) ([]byte, error) { - return []byte{}, nil -} - -func AssetDir(name string) ([]string, error) { - return []string{}, nil -} - -func RestoreAssets(dir, name string) error { - return nil -} -EOF -cat << EOF > bind_windows_amd64.go -// +build windows,amd64 - -// Placeholder file for assets binding -package main - -func Asset(name string) ([]byte, error) { - return []byte{}, nil -} - -func AssetDir(name string) ([]string, error) { - return []string{}, nil -} - -func RestoreAssets(dir, name string) error { - return nil -} -EOF diff --git a/cmd/agent-ui/resources/.gitignore b/cmd/agent-ui/resources/.gitignore deleted file mode 100644 index ababb72..0000000 --- a/cmd/agent-ui/resources/.gitignore +++ /dev/null @@ -1 +0,0 @@ -multires diff --git a/cmd/agent-ui/resources/AgentUI.svg b/cmd/agent-ui/resources/AgentUI.svg deleted file mode 100644 index 3aeca78..0000000 --- a/cmd/agent-ui/resources/AgentUI.svg +++ /dev/null @@ -1,1060 +0,0 @@ - - - - \ No newline at end of file diff --git a/cmd/agent-ui/resources/app/_headers b/cmd/agent-ui/resources/app/_headers deleted file mode 100755 index 6834fee..0000000 --- a/cmd/agent-ui/resources/app/_headers +++ /dev/null @@ -1,3 +0,0 @@ -/*.graphql - Content-Type: text/plain - Access-Control-Allow-Origin: * diff --git a/cmd/agent-ui/resources/app/_redirects b/cmd/agent-ui/resources/app/_redirects deleted file mode 100755 index c127d66..0000000 --- a/cmd/agent-ui/resources/app/_redirects +++ /dev/null @@ -1,2 +0,0 @@ -# general fallback -/* /index.html 200 diff --git a/cmd/agent-ui/resources/app/asset-manifest.json b/cmd/agent-ui/resources/app/asset-manifest.json deleted file mode 100644 index 8555e47..0000000 --- a/cmd/agent-ui/resources/app/asset-manifest.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "index.css": "static/css/index.css", - "index.css.map": "static/css/index.css.map", - "index.js": "static/js/index.js", - "index.js.map": "static/js/index.js.map", - "middleware.css": "static/css/middleware.css", - "middleware.css.map": "static/css/middleware.css.map", - "middleware.js": "static/js/middleware.js", - "middleware.js.map": "static/js/middleware.js.map", - "static/media/GraphQLLanguageService.js.flow": "static/media/GraphQLLanguageService.js.fa07138d.flow", - "static/media/autocompleteUtils.js.flow": "static/media/autocompleteUtils.js.4ce7ba19.flow", - "static/media/getAutocompleteSuggestions.js.flow": "static/media/getAutocompleteSuggestions.js.5f735c7b.flow", - "static/media/getDefinition.js.flow": "static/media/getDefinition.js.0c48668e.flow", - "static/media/getDiagnostics.js.flow": "static/media/getDiagnostics.js.889c0b27.flow", - "static/media/getOutline.js.flow": "static/media/getOutline.js.458a3518.flow", - "static/media/index.js.flow": "static/media/index.js.641230f5.flow", - "static/media/logo.png": "static/media/logo.57ee3b60.png" -} \ No newline at end of file diff --git a/cmd/agent-ui/resources/app/index.html b/cmd/agent-ui/resources/app/index.html deleted file mode 100644 index db054fe..0000000 --- a/cmd/agent-ui/resources/app/index.html +++ /dev/null @@ -1,15 +0,0 @@ -
f+p-3&&(a.scrollLeft=t.right+(d?0:10)-f),a}function Wn(e,t){null!=t&&(Yn(e),e.curOp.scrollTop=(null==e.curOp.scrollTop?e.doc.scrollTop:e.curOp.scrollTop)+t)}function Qn(e){Yn(e);var t=e.getCursor();e.curOp.scrollToPos={from:t,to:t,margin:e.options.cursorScrollMargin}}function Kn(e,t,n){null==t&&null==n||Yn(e),null!=t&&(e.curOp.scrollLeft=t),null!=n&&(e.curOp.scrollTop=n)}function Jn(e,t){Yn(e),e.curOp.scrollToPos=t}function Yn(e){var t=e.curOp.scrollToPos;if(t){e.curOp.scrollToPos=null;Xn(e,pn(e,t.from),pn(e,t.to),t.margin)}}function Xn(e,t,n,r){var i=Hn(e,{left:Math.min(t.left,n.left),top:Math.min(t.top,n.top)-r,right:Math.max(t.right,n.right),bottom:Math.max(t.bottom,n.bottom)+r});Kn(e,i.scrollLeft,i.scrollTop)}function Zn(e,t){Math.abs(e.doc.scrollTop-t)<2||(ma||Fr(e,{top:t}),er(e,t,!0),ma&&Fr(e),wr(e,100))}function er(e,t,n){t=Math.min(e.display.scroller.scrollHeight-e.display.scroller.clientHeight,t),(e.display.scroller.scrollTop!=t||n)&&(e.doc.scrollTop=t,e.display.scrollbars.setScrollTop(t),e.display.scroller.scrollTop!=t&&(e.display.scroller.scrollTop=t))}function tr(e,t,n,r){t=Math.min(t,e.display.scroller.scrollWidth-e.display.scroller.clientWidth),(n?t==e.doc.scrollLeft:Math.abs(e.doc.scrollLeft-t)<2)&&!r||(e.doc.scrollLeft=t,Un(e),e.display.scroller.scrollLeft!=t&&(e.display.scroller.scrollLeft=t),e.display.scrollbars.setScrollLeft(t))}function nr(e){var t=e.display,n=t.gutters.offsetWidth,r=Math.round(e.doc.height+Rt(e.display));return{clientHeight:t.scroller.clientHeight,viewHeight:t.wrapper.clientHeight,scrollWidth:t.scroller.scrollWidth,clientWidth:t.scroller.clientWidth,viewWidth:t.wrapper.clientWidth,barLeft:e.options.fixedGutter?n:0,docHeight:r,scrollHeight:r+$t(e)+t.barHeight,nativeBarWidth:t.nativeBarWidth,gutterWidth:n}}function rr(e,t){t||(t=nr(e));var n=e.display.barWidth,r=e.display.barHeight;ir(e,t);for(var i=0;i<4&&n!=e.display.barWidth||r!=e.display.barHeight;i++)n!=e.display.barWidth&&e.options.lineWrapping&&Rn(e),ir(e,nr(e)),n=e.display.barWidth,r=e.display.barHeight}function ir(e,t){var n=e.display,r=n.scrollbars.update(t);n.sizer.style.paddingRight=(n.barWidth=r.right)+"px",n.sizer.style.paddingBottom=(n.barHeight=r.bottom)+"px",n.heightForcer.style.borderBottom=r.bottom+"px solid transparent",r.right&&r.bottom?(n.scrollbarFiller.style.display="block",n.scrollbarFiller.style.height=r.bottom+"px",n.scrollbarFiller.style.width=r.right+"px"):n.scrollbarFiller.style.display="",r.bottom&&e.options.coverGutterNextToScrollbar&&e.options.fixedGutter?(n.gutterFiller.style.display="block",n.gutterFiller.style.height=r.bottom+"px",n.gutterFiller.style.width=t.gutterWidth+"px"):n.gutterFiller.style.display=""}function or(e){e.display.scrollbars&&(e.display.scrollbars.clear(),e.display.scrollbars.addClass&&Ra(e.display.wrapper,e.display.scrollbars.addClass)),e.display.scrollbars=new ws[e.options.scrollbarStyle](function(t){e.display.wrapper.insertBefore(t,e.display.scrollbarFiller),ns(t,"mousedown",function(){e.state.focused&&setTimeout(function(){return e.display.input.focus()},0)}),t.setAttribute("cm-not-content","true")},function(t,n){"horizontal"==n?tr(e,t):Zn(e,t)},e),e.display.scrollbars.addClass&&s(e.display.wrapper,e.display.scrollbars.addClass)}function ar(e){e.curOp={cm:e,viewChanged:!1,startHeight:e.doc.height,forceUpdate:!1,updateInput:null,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++Ss},vt(e.curOp)}function sr(e){xt(e.curOp,function(e){for(var t=0;t1e3||i.indexOf("\n")>-1?n.value=e.prevInput="":e.prevInput=i,e.composing&&(e.composing.range.clear(),e.composing.range=t.markText(e.composing.start,t.getCursor("to"),{className:"CodeMirror-composing"}))}),!0},nu.prototype.ensurePolled=function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},nu.prototype.onKeyPress=function(){ba&&xa>=9&&(this.hasSelection=null),this.fastPoll()},nu.prototype.onContextMenu=function(e){function t(){if(null!=a.selectionStart){var e=i.somethingSelected(),t="\u200b"+(e?a.value:"");a.value="\u21da",a.value=t,r.prevInput=e?"":"\u200b",a.selectionStart=1,a.selectionEnd=t.length,o.selForContextMenu=i.doc.sel}}function n(){if(r.contextMenuPending=!1,r.wrapper.style.cssText=l,a.style.cssText=c,ba&&xa<9&&o.scrollbars.setScrollTop(o.scroller.scrollTop=u),null!=a.selectionStart){(!ba||ba&&xa<9)&&t();var e=0,n=function(){o.selForContextMenu==i.doc.sel&&0==a.selectionStart&&a.selectionEnd>0&&"\u200b"==r.prevInput?mr(i,Ti)(i):e++<10?o.detectingSelectAll=setTimeout(n,500):(o.selForContextMenu=null,o.input.reset())};o.detectingSelectAll=setTimeout(n,200)}}var r=this,i=r.cm,o=i.display,a=r.textarea,s=kn(i,e),u=o.scroller.scrollTop;if(s&&!wa){i.options.resetSelectionOnContextMenu&&-1==i.doc.sel.contains(s)&&mr(i,Ei)(i.doc,Ur(s),Va);var c=a.style.cssText,l=r.wrapper.style.cssText;r.wrapper.style.cssText="position: absolute";var p=r.wrapper.getBoundingClientRect();a.style.cssText="position: absolute; width: 30px; height: 30px;\n top: "+(e.clientY-p.top-5)+"px; left: "+(e.clientX-p.left-5)+"px;\n z-index: 1000; background: "+(ba?"rgba(255, 255, 255, .05)":"transparent")+";\n outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";var f;if(Ea&&(f=window.scrollY),o.input.focus(),Ea&&window.scrollTo(null,f),o.input.reset(),i.somethingSelected()||(a.value=r.prevInput=" "),r.contextMenuPending=!0,o.selForContextMenu=i.doc.sel,clearTimeout(o.detectingSelectAll),ba&&xa>=9&&t(),ja){Le(e);var d=function(){ke(window,"mouseup",d),setTimeout(n,20)};ns(window,"mouseup",d)}else setTimeout(n,50)}},nu.prototype.readOnlyChanged=function(e){e||this.reset(),this.textarea.disabled="nocursor"==e},nu.prototype.setUneditable=function(){},nu.prototype.needsContentAttribute=!1,function(e){function t(t,r,i,o){e.defaults[t]=r,i&&(n[t]=o?function(e,t,n){n!=Js&&i(e,t,n)}:i)}var n=e.optionHandlers;e.defineOption=t,e.Init=Js,t("value","",function(e,t){return e.setValue(t)},!0),t("mode",null,function(e,t){e.doc.modeOption=t,Wr(e)},!0),t("indentUnit",2,Wr,!0),t("indentWithTabs",!1),t("smartIndent",!0),t("tabSize",4,function(e){Qr(e),nn(e),vr(e)},!0),t("lineSeparator",null,function(e,t){if(e.doc.lineSep=t,t){var n=[],r=e.doc.first;e.doc.iter(function(e){for(var i=0;;){var o=e.text.indexOf(t,i);if(-1==o)break;i=o+t.length,n.push(L(r,o))}r++});for(var i=n.length-1;i>=0;i--)ji(e.doc,t,n[i],L(n[i].line,n[i].ch+t.length))}}),t("specialChars",/[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/g,function(e,t,n){e.state.specialChars=new RegExp(t.source+(t.test("\t")?"":"|\t"),"g"),n!=Js&&e.refresh()}),t("specialCharPlaceholder",lt,function(e){return e.refresh()},!0),t("electricChars",!0),t("inputStyle",Oa?"contenteditable":"textarea",function(){throw new Error("inputStyle can not (yet) be changed in a running editor")},!0),t("spellcheck",!1,function(e,t){return e.getInputField().spellcheck=t},!0),t("rtlMoveVisually",!Ia),t("wholeLineUpdateBefore",!0),t("theme","default",function(e){qo(e),Vo(e)},!0),t("keyMap","default",function(e,t,n){var r=po(t),i=n!=Js&&po(n);i&&i.detach&&i.detach(e,r),r.attach&&r.attach(e,i||null)}),t("extraKeys",null),t("configureMouse",null),t("lineWrapping",!1,Wo,!0),t("gutters",[],function(e){Mr(e.options),Vo(e)},!0),t("fixedGutter",!0,function(e,t){e.display.gutters.style.left=t?Dn(e.display)+"px":"0",e.refresh()},!0),t("coverGutterNextToScrollbar",!1,function(e){return rr(e)},!0),t("scrollbarStyle","native",function(e){or(e),rr(e),e.display.scrollbars.setScrollTop(e.doc.scrollTop),e.display.scrollbars.setScrollLeft(e.doc.scrollLeft)},!0),t("lineNumbers",!1,function(e){Mr(e.options),Vo(e)},!0),t("firstLineNumber",1,Vo,!0),t("lineNumberFormatter",function(e){return e},Vo,!0),t("showCursorWhenSelecting",!1,An,!0),t("resetSelectionOnContextMenu",!0),t("lineWiseCopyCut",!0),t("pasteLinesPerSelection",!0),t("readOnly",!1,function(e,t){"nocursor"==t&&(jn(e),e.display.input.blur()),e.display.input.readOnlyChanged(t)}),t("disableInput",!1,function(e,t){t||e.display.input.reset()},!0),t("dragDrop",!0,Ho),t("allowDropFileTypes",null),t("cursorBlinkRate",530),t("cursorScrollMargin",0),t("cursorHeight",1,An,!0),t("singleCursorHeightPerLine",!0,An,!0),t("workTime",100),t("workDelay",100),t("flattenSpans",!0,Qr,!0),t("addModeClass",!1,Qr,!0),t("pollInterval",100),t("undoDepth",200,function(e,t){return e.doc.history.undoDepth=t}),t("historyEventDelay",1250),t("viewportMargin",10,function(e){return e.refresh()},!0),t("maxHighlightLength",1e4,Qr,!0),t("moveInputWithCursor",!0,function(e,t){t||e.display.input.resetPosition()}),t("tabindex",null,function(e,t){return e.display.input.getField().tabIndex=t||""}),t("autofocus",null),t("direction","ltr",function(e,t){return e.doc.setDirection(t)},!0)}(Qo),function(e){var t=e.optionHandlers,n=e.helpers={};e.prototype={constructor:e,focus:function(){window.focus(),this.display.input.focus()},setOption:function(e,n){var r=this.options,i=r[e];r[e]==n&&"mode"!=e||(r[e]=n,t.hasOwnProperty(e)&&mr(this,t[e])(this,n,i),_e(this,"optionChange",this,e))},getOption:function(e){return this.options[e]},getDoc:function(){return this.doc},addKeyMap:function(e,t){this.state.keyMaps[t?"push":"unshift"](po(e))},removeKeyMap:function(e){for(var t=this.state.keyMaps,n=0;n>>=1)a[s]=1&n?t[o++]:void 0;return a[r]=i,new sr(e,o+1,a)}function ut(e){return e-=e>>1&1431655765,e=(858993459&e)+(e>>2&858993459),e=e+(e>>4)&252645135,e+=e>>8,127&(e+=e>>16)}function ct(e,t,n,r){var i=r?e:pe(e);return i[t]=n,i}function lt(e,t,n,r){var i=e.length+1;if(r&&t+1===i)return e[t]=n,e;for(var o=new Array(i),a=0,s=0;so?0:o-n,c=a-n;return c>cn&&(c=cn),function(){if(i===c)return xr;var e=t?--c:i++;return r&&r[e]}}function i(e,r,i){var s,u=e&&e.array,c=i>o?0:o-i>>r,l=1+(a-i>>r);return l>cn&&(l=cn),function(){for(;;){if(s){var e=s();if(e!==xr)return e;s=null}if(c===l)return xr;var o=t?--l:c++;s=n(u&&u[o],r-un,i+(o<=dr)return st(e,f,c,s,h);if(l&&!h&&2===f.length&&rt(f[1^p]))return f[1^p];if(l&&h&&1===f.length&&rt(h))return h;var m=e&&e===this.ownerID,g=l?h?c:c^u:c|u,y=l?h?ct(f,p,h,m):pt(f,p,m):lt(f,p,h,m);return m?(this.bitmap=g,this.nodes=y,this):new ar(e,g,y)};var sr=function(e,t,n){this.ownerID=e,this.count=t,this.nodes=n};sr.prototype.get=function(e,t,n,r){void 0===t&&(t=j(n));var i=(0===e?t:t>>>e)&ln,o=this.nodes[i];return o?o.get(e+un,t,n,r):r},sr.prototype.update=function(e,t,n,r,i,o,a){void 0===n&&(n=j(r));var s=(0===t?n:n>>>t)&ln,u=i===pn,c=this.nodes,l=c[s];if(u&&!l)return this;var p=nt(l,e,t+un,n,r,i,o,a);if(p===l)return this;var f=this.count;if(l){if(!p&&--f
0&&ii?0:i+n),r=r===ne||r>i?i:vu(r),r<0&&(r+=i),r=n>r?0:bu(r);n=120&&l.length>=120)?new hn(a&&l):ne}l=e[0];var h=-1,m=s[0];e:for(;++h-1;)s!==e&&kl.call(s,u,1),kl.call(e,u,1);return e}function Kr(e,t){for(var n=e?t.length:0,r=n-1;n--;){var i=t[n];if(n==r||i!==o){var o=i;Oo(i)?kl.call(e,i,1):fi(e,i)}}return e}function Jr(e,t){return e+Ll(Vl()*(t-e+1))}function Yr(e,t,n,r){for(var i=-1,o=Ul(Pl((t-e)/(n||1)),0),a=Xc(o);o--;)a[r?o:++i]=e,e+=n;return a}function Xr(e,t){var n="";if(!e||t<1||t>Fe)return n;do{t%2&&(n+=e),(t=Ll(t/2))&&(e+=e)}while(t);return n}function Zr(e,t){return kp(zo(e,t,kc),e+"")}function ei(e){return Fn(Ku(e))}function ti(e,t){var n=Ku(e);return Qo(n,Zn(t,0,n.length))}function ni(e,t,n,r){if(!eu(e))return e;t=xi(t,e);for(var i=-1,o=t.length,a=o-1,s=e;null!=s&&++i
1?"& ":"")+t[r],t=t.join(n>2?", ":" "),e.replace(Pt,"{\n/* [wrapped with "+t+"] */\n")}function To(e){return df(e)||ff(e)||!!(_l&&e&&e[_l])}function Oo(e,t){var n=typeof e;return!!(t=null==t?Fe:t)&&("number"==n||"symbol"!=n&&Vt.test(e))&&e>-1&&e%1==0&&e1&&h.reverse(),_&&w-1&&(s=o?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n"))):s=e.stylize("[Circular]","special")),E(a)){if(o&&i.match(/^\d+$/))return s;a=JSON.stringify(""+i),a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function d(e,t,n){var r=0;return e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function h(e){return Array.isArray(e)}function m(e){return"boolean"===typeof e}function g(e){return null===e}function y(e){return null==e}function v(e){return"number"===typeof e}function b(e){return"string"===typeof e}function x(e){return"symbol"===typeof e}function E(e){return void 0===e}function C(e){return D(e)&&"[object RegExp]"===A(e)}function D(e){return"object"===typeof e&&null!==e}function w(e){return D(e)&&"[object Date]"===A(e)}function S(e){return D(e)&&("[object Error]"===A(e)||e instanceof Error)}function k(e){return"function"===typeof e}function _(e){return null===e||"boolean"===typeof e||"number"===typeof e||"string"===typeof e||"symbol"===typeof e||"undefined"===typeof e}function A(e){return Object.prototype.toString.call(e)}function T(e){return e<10?"0"+e.toString(10):e.toString(10)}function O(){var e=new Date,t=[T(e.getHours()),T(e.getMinutes()),T(e.getSeconds())].join(":");return[e.getDate(),L[e.getMonth()],t].join(" ")}function F(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var N=/%[sdj%]/g;t.format=function(e){if(!b(e)){for(var t=[],n=0;n