(command.CommandList
  children: [
    (command.If
      arms: [
        (if_arm
          cond: [
            (command.Sentence
              child: (C {(test)} {(-z)} {(DQ ($ Id.VSub_DollarName '$BASH_VERSION'))})
              terminator: (Token id:Id.Op_Semi val:';' span_id:113)
            )
          ]
          action: [
            (command.Simple
              words: [{(echo)} {(DQ ('Please run this script using bash, not sh or any other shell.'))}]
              redirects: [
                (redir.Redir
                  op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:124)
                  fd: -1
                  arg_word: {(2)}
                )
              ]
            )
            (command.ControlFlow
              token: (Token id:Id.ControlFlow_Exit val:exit span_id:128)
              arg_word: {(1)}
            )
          ]
          spids: [104 115]
        )
      ]
    )
    (command.ShFunction
      name: _
      body: 
        (command.BraceGroup
          children: [
            (C {(Id.KW_Set set)} {(-euo)} {(pipefail)})
            (C {(declare)} {(-a)} {(ORIGINAL_ARGS)})
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:CURL_USER_AGENT)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: (Token id:Id.VSub_Name val:CURL_USER_AGENT span_id:186)
                          suffix_op: 
                            (suffix_op.Unary
                              op_id: Id.VTest_ColonHyphen
                              arg_word: {(sandstorm-install-script)}
                            )
                        )
                      )
                    }
                  spids: [183]
                )
              ]
            )
            (command.ShFunction
              name: error
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {($ Id.VSub_Pound '$#')} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(0)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:215)
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [
                                {(echo)}
                                {(-en)}
                                {(SQ (Token id:Id.Lit_Chars val:'\\e[0;31m' span_id:225))}
                              ]
                              redirects: [
                                (redir.Redir
                                  op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:228)
                                  fd: -1
                                  arg_word: {(2)}
                                )
                              ]
                            )
                            (command.Pipeline
                              children: [
                                (C {(echo)} {(DQ ($ Id.VSub_At '$@'))})
                                (command.Subshell
                                  command_list: 
                                    (command.CommandList
                                      children: [
                                        (command.AndOr
                                          ops: [Id.Op_DPipe]
                                          children: [(C {(fold)} {(-s)}) (C {(cat)})]
                                        )
                                      ]
                                    )
                                  redirects: [
                                    (redir.Redir
                                      op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:250)
                                      fd: -1
                                      arg_word: {(2)}
                                    )
                                  ]
                                )
                              ]
                              negated: F
                            )
                            (command.Simple
                              words: [
                                {(echo)}
                                {(-en)}
                                {(SQ (Token id:Id.Lit_Chars val:'\\e[0m' span_id:259))}
                              ]
                              redirects: [
                                (redir.Redir
                                  op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:262)
                                  fd: -1
                                  arg_word: {(2)}
                                )
                              ]
                            )
                          ]
                          spids: [203 217]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: fail
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Id.Lit_VarLike 'error_code=') (DQ ($ Id.VSub_Number '$1'))})
                    (C {(shift)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: 
                                          (Token
                                            id: Id.VSub_Name
                                            val: SHOW_FAILURE_MSG
                                            span_id: 295
                                          )
                                        suffix_op: 
                                          (suffix_op.Unary
                                            op_id: Id.VTest_ColonHyphen
                                            arg_word: {(yes)}
                                          )
                                      )
                                    )
                                  } {(Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:309)
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [{(echo)} {(DQ ('*** INSTALLATION FAILED ***'))}]
                              redirects: [
                                (redir.Redir
                                  op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:320)
                                  fd: -1
                                  arg_word: {(2)}
                                )
                              ]
                            )
                            (C {(echo)} {(DQ )})
                          ]
                          spids: [289 311]
                        )
                      ]
                    )
                    (C {(error)} {(DQ ($ Id.VSub_At '$@'))})
                    (command.Simple
                      words: [{(echo)} {(DQ )}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:345)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:REPORT span_id:359)
                                        suffix_op: 
                                          (suffix_op.Unary
                                            op_id: Id.VTest_ColonHyphen
                                            arg_word: {(yes)}
                                          )
                                      )
                                    )
                                  } {(Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:373)
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.Simple
                                          words: [
                                            {(prompt-yesno)}
                                            {
                                              (DQ 
                                                (
'Hmm, installation failed. Would it be OK to send an anonymous error report to the sandstorm.io team so we know something is wrong?\n'
                                                ) ('It would only contain this error code: ') ($ Id.VSub_DollarName '$error_code')
                                              )
                                            }
                                            {(DQ (yes))}
                                          ]
                                          more_env: [
                                            (env_pair
                                              name: USE_DEFAULTS
                                              val: {(no)}
                                              spids: [380]
                                            )
                                          ]
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:395)
                                    )
                                  ]
                                  action: [
                                    (command.Simple
                                      words: [{(echo)} {(DQ ('Sending problem report...'))}]
                                      redirects: [
                                        (redir.Redir
                                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:406)
                                          fd: -1
                                          arg_word: {(2)}
                                        )
                                      ]
                                    )
                                    (C {(local)} 
                                      {(Id.Lit_VarLike 'BEARER_TOKEN=') 
                                        (DQ (ZiV1jbwHBPfpIjF3LNFv9-glp53F7KcsvVvljgKxQAL))
                                      }
                                    )
                                    (C {(local)} 
                                      {(Id.Lit_VarLike 'API_ENDPOINT=') 
                                        (DQ ('https://api.oasis.sandstorm.io/api'))
                                      }
                                    )
                                    (C {(local)} 
                                      {(Id.Lit_VarLike 'HTTP_STATUS=') 
                                        (command_sub
                                          left_token: 
                                            (Token
                                              id: Id.Left_DollarParen
                                              val: '$('
                                              span_id: 429
                                            )
                                          command_list: 
                                            (command.CommandList
                                              children: [
                                                (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                                  {(--data-binary)} 
                                                  {
                                                    (DQ ('{') 
                                                      (word_part.EscapedLiteral
                                                        token: 
                                                          (Token
                                                            id: Id.Lit_EscapedChar
                                                            val: '\\"'
                                                            span_id: 450
                                                          )
                                                      ) (error_code) (word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\"' span_id:452)) (':') 
                                                      (word_part.EscapedLiteral
                                                        token: 
                                                          (Token
                                                            id: Id.Lit_EscapedChar
                                                            val: '\\"'
                                                            span_id: 454
                                                          )
                                                      ) ($ Id.VSub_DollarName '$error_code') 
                                                      (word_part.EscapedLiteral
                                                        token: 
                                                          (Token
                                                            id: Id.Lit_EscapedChar
                                                            val: '\\"'
                                                            span_id: 456
                                                          )
                                                      ) (',') (word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\"' span_id:458)) (user-agent) 
                                                      (word_part.EscapedLiteral
                                                        token: 
                                                          (Token
                                                            id: Id.Lit_EscapedChar
                                                            val: '\\"'
                                                            span_id: 460
                                                          )
                                                      ) (':') (word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\"' span_id:462)) 
                                                      ($ Id.VSub_DollarName '$CURL_USER_AGENT') (word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\"' span_id:464)) ('}')
                                                    )
                                                  } {(-H)} {(DQ ('Authorization: Bearer ') ($ Id.VSub_DollarName '$BEARER_TOKEN'))} {(-X)} {(POST)} 
                                                  {(--output)} {(DQ (/dev/null))} {(-w)} {(SQ (Token id:Id.Lit_Chars val:'%{http_code}' span_id:496))} 
                                                  {(DQ ($ Id.VSub_DollarName '$API_ENDPOINT'))}
                                                )
                                              ]
                                            )
                                        )
                                      }
                                    )
                                    (command.If
                                      arms: [
                                        (if_arm
                                          cond: [
                                            (command.Sentence
                                              child: 
                                                (C {(Id.Lit_LBracket '[')} {(DQ (200))} 
                                                  {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {(Id.Lit_RBracket ']')}
                                                )
                                              terminator: (Token id:Id.Op_Semi val:';' span_id:524)
                                            )
                                          ]
                                          action: [
                                            (command.Simple
                                              words: [
                                                {(echo)}
                                                {
                                                  (DQ 
                                                    (
'... problem reported successfully. Your installation did not succeed.'
                                                    )
                                                  )
                                                }
                                              ]
                                              redirects: [
                                                (redir.Redir
                                                  op: 
                                                    (Token
                                                      id: Id.Redir_GreatAnd
                                                      val: '>&'
                                                      span_id: 535
                                                    )
                                                  fd: -1
                                                  arg_word: {(2)}
                                                )
                                              ]
                                            )
                                          ]
                                          spids: [507 526]
                                        )
                                        (if_arm
                                          cond: [
                                            (command.Sentence
                                              child: 
                                                (C {(Id.Lit_LBracket '[')} {(DQ (000))} 
                                                  {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {(Id.Lit_RBracket ']')}
                                                )
                                              terminator: (Token id:Id.Op_Semi val:';' span_id:556)
                                            )
                                          ]
                                          action: [
                                            (C {(error)} 
                                              {
                                                (DQ 
                                                  (
'Submitting error report failed. Maybe there is a connectivity problem.'
                                                  )
                                                )
                                              }
                                            )
                                          ]
                                          spids: [539 558]
                                        )
                                      ]
                                      else_action: [
                                        (C {(error)} 
                                          {
                                            (DQ 
                                              (
'Submitting error report resulted in strange HTTP status: '
                                              ) ($ Id.VSub_DollarName '$HTTP_STATUS')
                                            )
                                          }
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [378 397]
                                )
                              ]
                              else_action: [
                                (command.Simple
                                  words: [{(echo)} {(DQ ('Not sending report.'))}]
                                  redirects: [
                                    (redir.Redir
                                      op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:591)
                                      fd: -1
                                      arg_word: {(2)}
                                    )
                                  ]
                                )
                              ]
                            )
                            (C {(echo)} {(DQ )})
                          ]
                          spids: [353 375]
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {(DQ ('You can report bugs at: http://github.com/sandstorm-io/sandstorm'))}
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:613)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (command.ControlFlow
                      token: (Token id:Id.ControlFlow_Exit val:exit span_id:617)
                      arg_word: {(1)}
                    )
                  ]
                )
            )
            (command.ShFunction
              name: retryable_curl
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Id.Lit_VarLike 'CURL_FAILED=') (DQ (no))})
                    (command.AndOr
                      ops: [Id.Op_DPipe]
                      children: [
                        (command.Simple
                          words: [
                            {(curl)}
                            {(-A)}
                            {(DQ (${ Id.VSub_Name CURL_USER_AGENT))}
                            {(-f)}
                            {(DQ ($ Id.VSub_Number '$1'))}
                          ]
                          redirects: [
                            (redir.Redir
                              op: (Token id:Id.Redir_Great val:'>' span_id:663)
                              fd: -1
                              arg_word: {(DQ ($ Id.VSub_Number '$2'))}
                            )
                          ]
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:CURL_FAILED)
                              op: assign_op.Equal
                              rhs: {(DQ (yes))}
                              spids: [671]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ (${ Id.VSub_Name CURL_FAILED))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:695)
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} 
                                          {
                                            (DQ ('Downloading ') ($ Id.VSub_Number '$1') 
                                              (' failed. OK to retry?')
                                            )
                                          } {(DQ (yes))}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:714)
                                    )
                                  ]
                                  action: [
                                    (command.Simple
                                      words: [{(echo)} {(DQ )}]
                                      redirects: [
                                        (redir.Redir
                                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:724)
                                          fd: -1
                                          arg_word: {(2)}
                                        )
                                      ]
                                    )
                                    (command.Simple
                                      words: [
                                        {(echo)}
                                        {
                                          (DQ 
                                            (
'Download failed. Waiting one second before retrying...'
                                            )
                                          )
                                        }
                                      ]
                                      redirects: [
                                        (redir.Redir
                                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:734)
                                          fd: -1
                                          arg_word: {(2)}
                                        )
                                      ]
                                    )
                                    (C {(sleep)} {(1)})
                                    (C {(retryable_curl)} {(DQ ($ Id.VSub_Number '$1'))} 
                                      {(DQ ($ Id.VSub_Number '$2'))}
                                    )
                                  ]
                                  spids: [700 716]
                                )
                              ]
                            )
                          ]
                          spids: [677 697]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: dotdotdot_curl
              body: 
                (command.BraceGroup
                  children: [
                    (command.Simple
                      words: [{(echo)} {(-n)} {(SQ (Token id:Id.Lit_Chars val:... span_id:828))}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:831)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (C {(curl)} {(DQ ($ Id.VSub_At '$@'))})
                    (command.Simple
                      words: [{(echo)} {(-ne)} {(SQ (Token id:Id.Lit_Chars val:'\\r' span_id:849))}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:852)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: is_port_bound
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Id.Lit_VarLike 'SCAN_HOST=') (DQ ($ Id.VSub_Number '$1'))})
                    (C {(local)} {(Id.Lit_VarLike 'SCAN_PORT=') (DQ ($ Id.VSub_Number '$2'))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (${ Id.VSub_Name DEV_TCP_USABLE))} 
                                  {(Id.Lit_Equals '=')} {(DQ (unchecked))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:900)
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [
                                {(fail)}
                                {(DQ (E_DEV_TCP_UNCHECKED))}
                                {
                                  (DQ 
                                    (
'Programmer error. The author of install.sh used an uninitialized variable.'
                                    )
                                  )
                                }
                              ]
                              more_env: [(env_pair name:REPORT val:{(no)} spids:[905])]
                            )
                          ]
                          spids: [882 902]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (${ Id.VSub_Name DEV_TCP_USABLE))} 
                                  {(Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:949)
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.Simple
                                          words: [
                                            {(timeout)}
                                            {(1)}
                                            {(bash)}
                                            {(-c)}
                                            {
                                              (DQ (': < /dev/tcp/') (${ Id.VSub_Name SCAN_HOST) (/) 
                                                (${ Id.VSub_Name SCAN_PORT)
                                              )
                                            }
                                          ]
                                          redirects: [
                                            (redir.Redir
                                              op: (Token id:Id.Redir_Great val:'2>' span_id:975)
                                              fd: 2
                                              arg_word: {(/dev/null)}
                                            )
                                          ]
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:977)
                                    )
                                  ]
                                  action: [
                                    (command.ControlFlow
                                      token: (Token id:Id.ControlFlow_Return val:return span_id:982)
                                      arg_word: {(0)}
                                    )
                                  ]
                                  spids: [954 979]
                                )
                              ]
                              else_action: [
                                (command.ControlFlow
                                  token: (Token id:Id.ControlFlow_Return val:return span_id:990)
                                  arg_word: {(1)}
                                )
                              ]
                            )
                          ]
                          spids: [931 951]
                        )
                      ]
                    )
                    (C {(local)} {(Id.Lit_VarLike 'DEBIAN_STYLE_INDICATED_BOUND=') (DQ (no))})
                    (command.AndOr
                      ops: [Id.Op_DAmp]
                      children: [
                        (command.Simple
                          words: [
                            {(${ Id.VSub_Name NC_PATH)}
                            {(-z)}
                            {(DQ ($ Id.VSub_DollarName '$SCAN_HOST'))}
                            {(DQ ($ Id.VSub_DollarName '$SCAN_PORT'))}
                          ]
                          redirects: [
                            (redir.Redir
                              op: (Token id:Id.Redir_Great val:'>' span_id:1092)
                              fd: -1
                              arg_word: {(/dev/null)}
                            )
                            (redir.Redir
                              op: (Token id:Id.Redir_Great val:'2>' span_id:1095)
                              fd: 2
                              arg_word: {(/dev/null)}
                            )
                          ]
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:DEBIAN_STYLE_INDICATED_BOUND)
                              op: assign_op.Equal
                              rhs: {(yes)}
                              spids: [1100]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {(DQ ($ Id.VSub_DollarName '$DEBIAN_STYLE_INDICATED_BOUND'))} {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:1122)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:1127)
                              arg_word: {(0)}
                            )
                          ]
                          spids: [1105 1124]
                        )
                      ]
                    )
                    (C {(local)} {(Id.Lit_VarLike 'NMAP_STYLE_INDICATED_BOUND=') (DQ (no))})
                    (command.AndOr
                      ops: [Id.Op_DAmp]
                      children: [
                        (command.Simple
                          words: [
                            {(${ Id.VSub_Name NC_PATH)}
                            {(--wait)}
                            {(1)}
                            {(--recv-only)}
                            {(--send-only)}
                            {(DQ ($ Id.VSub_DollarName '$SCAN_HOST'))}
                            {(DQ ($ Id.VSub_DollarName '$SCAN_PORT'))}
                          ]
                          redirects: [
                            (redir.Redir
                              op: (Token id:Id.Redir_Great val:'>' span_id:1168)
                              fd: -1
                              arg_word: {(/dev/null)}
                            )
                            (redir.Redir
                              op: (Token id:Id.Redir_Great val:'2>' span_id:1171)
                              fd: 2
                              arg_word: {(/dev/null)}
                            )
                          ]
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:NMAP_STYLE_INDICATED_BOUND)
                              op: assign_op.Equal
                              rhs: {(yes)}
                              spids: [1178]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {(DQ ($ Id.VSub_DollarName '$NMAP_STYLE_INDICATED_BOUND'))} {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:1200)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:1205)
                              arg_word: {(0)}
                            )
                          ]
                          spids: [1183 1202]
                        )
                      ]
                    )
                    (command.ControlFlow
                      token: (Token id:Id.ControlFlow_Return val:return span_id:1222)
                      arg_word: {(1)}
                    )
                  ]
                )
            )
            (command.ShFunction
              name: writeConfig
              body: 
                (command.BraceGroup
                  children: [
                    (command.WhileUntil
                      keyword: (Token id:Id.KW_While val:while span_id:1245)
                      cond: [
                        (command.Sentence
                          child: 
                            (C {(Id.Lit_LBracket '[')} {($ Id.VSub_Pound '$#')} {(-gt)} {(0)} 
                              {(Id.Lit_RBracket ']')}
                            )
                          terminator: (Token id:Id.Op_Semi val:';' span_id:1256)
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(eval)} {(echo)} 
                              {
                                (DQ ($ Id.VSub_Number '$1') ('=') 
                                  (word_part.EscapedLiteral
                                    token: (Token id:Id.Lit_EscapedChar val:'\\$' span_id:1268)
                                  ) ($ Id.VSub_Number '$1')
                                )
                              }
                            )
                            (C {(shift)})
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShFunction
              name: prompt
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(VALUE)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:1322)
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ($ Id.VSub_Number '$2'))})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:1338)
                            )
                          ]
                          spids: [1306 1324]
                        )
                      ]
                    )
                    (command.Simple
                      words: [{(echo)} {(-en)} {(SQ (Token id:Id.Lit_Chars val:'\\e[1m' span_id:1354))}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1357)
                          fd: -1
                          arg_word: {(3)}
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {(-n)}
                        {(DQ ($ Id.VSub_Number '$1') (' [') ($ Id.VSub_Number '$2') (']'))}
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1372)
                          fd: -1
                          arg_word: {(3)}
                        )
                      ]
                    )
                    (command.Simple
                      words: [{(echo)} {(-en)} {(SQ (Token id:Id.Lit_Chars val:'\\e[0m ' span_id:1381))}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1384)
                          fd: -1
                          arg_word: {(3)}
                        )
                      ]
                    )
                    (C {(read)} {(-u)} {(3)} {(VALUE)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-z)} {(DQ ($ Id.VSub_DollarName '$VALUE'))} 
                                  {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:1408)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:VALUE)
                                  op: assign_op.Equal
                                  rhs: {($ Id.VSub_Number '$2')}
                                  spids: [1413]
                                )
                              ]
                            )
                          ]
                          spids: [1397 1410]
                        )
                      ]
                    )
                    (C {(echo)} {(DQ ($ Id.VSub_DollarName '$VALUE'))})
                  ]
                )
            )
            (command.ShFunction
              name: prompt-numeric
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Id.Lit_VarLike 'NUMERIC_REGEX=') (DQ ('^[0-9]+') (Id.Lit_Other '$'))})
                    (command.WhileUntil
                      keyword: (Token id:Id.KW_While val:while span_id:1445)
                      cond: [
                        (command.Sentence
                          child: (C {(true)})
                          terminator: (Token id:Id.Op_Semi val:';' span_id:1448)
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(local)} 
                              {(Id.Lit_VarLike 'VALUE=') 
                                (command_sub
                                  left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:1456)
                                  command_list: 
                                    (command.CommandList
                                      children: [(C {(prompt)} {(DQ ($ Id.VSub_At '$@'))})]
                                    )
                                )
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.Pipeline
                                          children: [
                                            (command.DBracket
                                              expr: 
                                                (bool_expr.Binary
                                                  op_id: Id.BoolBinary_EqualTilde
                                                  left: {(DQ ($ Id.VSub_DollarName '$VALUE'))}
                                                  right: {($ Id.VSub_DollarName '$NUMERIC_REGEX')}
                                                )
                                            )
                                          ]
                                          negated: T
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:1482)
                                    )
                                  ]
                                  action: [
                                    (command.Simple
                                      words: [
                                        {(echo)}
                                        {
                                          (DQ ("You entered '") ($ Id.VSub_DollarName '$VALUE') 
                                            ("'. Please enter a number.")
                                          )
                                        }
                                      ]
                                      redirects: [
                                        (redir.Redir
                                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1495)
                                          fd: -1
                                          arg_word: {(3)}
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [1466 1484]
                                )
                              ]
                              else_action: [
                                (C {(echo)} {(DQ ($ Id.VSub_DollarName '$VALUE'))})
                                (command.ControlFlow
                                  token: (Token id:Id.ControlFlow_Return val:return span_id:1509)
                                )
                              ]
                            )
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShFunction
              name: prompt-yesno
              body: 
                (command.BraceGroup
                  children: [
                    (command.WhileUntil
                      keyword: (Token id:Id.KW_While val:while span_id:1527)
                      cond: [
                        (command.Sentence
                          child: (C {(true)})
                          terminator: (Token id:Id.Op_Semi val:';' span_id:1530)
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(local)} 
                              {(Id.Lit_VarLike 'VALUE=') 
                                (command_sub
                                  left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:1538)
                                  command_list: 
                                    (command.CommandList
                                      children: [(C {(prompt)} {(DQ ($ Id.VSub_At '$@'))})]
                                    )
                                )
                              }
                            )
                            (command.Case
                              to_match: {($ Id.VSub_DollarName '$VALUE')}
                              arms: [
                                (case_arm
                                  pat_list: [{(y)} {(Y)} {(yes)} {(YES)} {(Yes)}]
                                  action: [
                                    (command.ControlFlow
                                      token: (Token id:Id.ControlFlow_Return val:return span_id:1576)
                                      arg_word: {(0)}
                                    )
                                  ]
                                  spids: [1555 1573 1581 -1]
                                )
                                (case_arm
                                  pat_list: [{(n)} {(N)} {(no)} {(NO)} {(No)}]
                                  action: [
                                    (command.ControlFlow
                                      token: (Token id:Id.ControlFlow_Return val:return span_id:1605)
                                      arg_word: {(1)}
                                    )
                                  ]
                                  spids: [1584 1602 1610 -1]
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('*** Please answer ') 
                                  (word_part.EscapedLiteral
                                    token: (Token id:Id.Lit_EscapedChar val:'\\"' span_id:1621)
                                  ) (yes) (word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\"' span_id:1623)) (' or ') 
                                  (word_part.EscapedLiteral
                                    token: (Token id:Id.Lit_EscapedChar val:'\\"' span_id:1625)
                                  ) (no) (word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\"' span_id:1627)) (.)
                                )
                              }
                            )
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:USE_DEFAULTS)
                  op: assign_op.Equal
                  rhs: {(DQ (no))}
                  spids: [1644]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                  op: assign_op.Equal
                  rhs: {(DQ (no))}
                  spids: [1649]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:USE_SANDCATS)
                  op: assign_op.Equal
                  rhs: {(DQ (no))}
                  spids: [1654]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL)
                  op: assign_op.Equal
                  rhs: {(DQ (no))}
                  spids: [1659]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:SANDCATS_HTTPS_SUCCESSFUL)
                  op: assign_op.Equal
                  rhs: {(DQ (no))}
                  spids: [1664]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:CURRENTLY_UID_ZERO)
                  op: assign_op.Equal
                  rhs: {(DQ (no))}
                  spids: [1669]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:PREFER_ROOT)
                  op: assign_op.Equal
                  rhs: {(DQ (yes))}
                  spids: [1674]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:SHOW_MESSAGE_ABOUT_NEEDING_PORTS_OPEN)
                  op: assign_op.Equal
                  rhs: {(DQ (no))}
                  spids: [1679]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:STARTED_SANDSTORM)
                  op: assign_op.Equal
                  rhs: {(DQ (no))}
                  spids: [1684]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:NC_PATH)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: (Token id:Id.VSub_Name val:OVERRIDE_NC_PATH span_id:1699)
                          suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:{(nc)})
                        )
                      )
                    }
                  spids: [1696]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEV_TCP_USABLE)
                  op: assign_op.Equal
                  rhs: {(DQ (unchecked))}
                  spids: [1709]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEFAULT_DIR_FOR_ROOT)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: 
                            (Token
                              id: Id.VSub_Name
                              val: OVERRIDE_SANDSTORM_DEFAULT_DIR
                              span_id: 1724
                            )
                          suffix_op: 
                            (suffix_op.Unary
                              op_id: Id.VTest_ColonHyphen
                              arg_word: {(Id.Lit_Slash /) (opt) (Id.Lit_Slash /) (sandstorm)}
                            )
                        )
                      )
                    }
                  spids: [1721]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEFAULT_DIR_FOR_NON_ROOT)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: 
                            (Token
                              id: Id.VSub_Name
                              val: OVERRIDE_SANDSTORM_DEFAULT_DIR
                              span_id: 1736
                            )
                          suffix_op: 
                            (suffix_op.Unary
                              op_id: Id.VTest_ColonHyphen
                              arg_word: 
                                {
                                  (braced_var_sub
                                    token: (Token id:Id.VSub_Name val:HOME span_id:1739)
                                    suffix_op: 
                                      (suffix_op.Unary
                                        op_id: Id.VTest_ColonHyphen
                                        arg_word: {(opt)}
                                      )
                                  ) (Id.Lit_Slash /) (sandstorm)
                                }
                            )
                        )
                      )
                    }
                  spids: [1733]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEFAULT_SMTP_PORT)
                  op: assign_op.Equal
                  rhs: {(DQ (30025))}
                  spids: [1748]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEFAULT_UPDATE_CHANNEL)
                  op: assign_op.Equal
                  rhs: {(DQ (dev))}
                  spids: [1753]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEFAULT_SERVER_USER)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: 
                            (Token
                              id: Id.VSub_Name
                              val: OVERRIDE_SANDSTORM_DEFAULT_SERVER_USER
                              span_id: 1761
                            )
                          suffix_op: 
                            (suffix_op.Unary
                              op_id: Id.VTest_ColonHyphen
                              arg_word: {(sandstorm)}
                            )
                        )
                      )
                    }
                  spids: [1758]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:SANDCATS_BASE_DOMAIN)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: 
                            (Token
                              id: Id.VSub_Name
                              val: OVERRIDE_SANDCATS_BASE_DOMAIN
                              span_id: 1770
                            )
                          suffix_op: 
                            (suffix_op.Unary
                              op_id: Id.VTest_ColonHyphen
                              arg_word: {(sandcats.io)}
                            )
                        )
                      )
                    }
                  spids: [1767]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:ALLOW_DEV_ACCOUNTS)
                  op: assign_op.Equal
                  rhs: {(DQ (false))}
                  spids: [1776]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:SANDCATS_GETCERTIFICATE)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: 
                            (Token
                              id: Id.VSub_Name
                              val: OVERRIDE_SANDCATS_GETCERTIFICATE
                              span_id: 1784
                            )
                          suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:{(yes)})
                        )
                      )
                    }
                  spids: [1781]
                )
              ]
            )
            (command.ShFunction
              name: usage
              body: 
                (command.BraceGroup
                  children: [
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (DQ ('usage: ') ($ Id.VSub_DollarName '$SCRIPT_NAME') 
                            (' [-d] [-e] [-p PORT_NUMBER] [-u] [<bundle>]')
                          )
                        }
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1810)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (DQ 
                            (
'If <bundle> is provided, it must be the name of a Sandstorm bundle file,'
                            )
                          )
                        }
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1820)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (DQ 
                            (
"like 'sandstorm-123.tar.xz', which will be installed. Otherwise, the script"
                            )
                          )
                        }
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1830)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (command.Simple
                      words: [{(echo)} {(DQ ('downloads a bundle from the internet via HTTP.'))}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1840)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (command.Simple
                      words: [{(echo)} {(SQ )}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1849)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (SQ 
                            (Token
                              id: Id.Lit_Chars
                              val: 
'If -d is specified, the auto-installs with defaults suitable for app development.'
                              span_id: 1856
                            )
                          )
                        }
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1859)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (SQ 
                            (Token
                              id: Id.Lit_Chars
                              val: 
'If -e is specified, default to listening on an external interface, not merely loopback.'
                              span_id: 1866
                            )
                          )
                        }
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1869)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (SQ 
                            (Token
                              id: Id.Lit_Chars
                              val: 
'If -i is specified, default to (i)nsecure mode where we do not request a HTTPS certificate.'
                              span_id: 1876
                            )
                          )
                        }
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1879)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (SQ 
                          (Token
                            id: Id.Lit_Chars
                            val: 
'If -p is specified, use its argument (PORT_NUMBER) as the default port for HTTP. Otherwise, use 6080. Note that if the install script enables HTTPS via sandcats.io, it will use 443 instead!'
                            span_id: 1886
                          )
                        )
                      }
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (SQ 
                            (Token
                              id: Id.Lit_Chars
                              val: 
'If -u is specified, default to avoiding root priviliges. Note that the dev tools only work if the server as root privileges.'
                              span_id: 1893
                            )
                          )
                        }
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:1896)
                          fd: -1
                          arg_word: {(2)}
                        )
                      ]
                    )
                    (command.ControlFlow
                      token: (Token id:Id.ControlFlow_Exit val:exit span_id:1900)
                      arg_word: {(1)}
                    )
                  ]
                )
            )
            (command.ShFunction
              name: detect_current_uid
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {
                                    (command_sub
                                      left_token: 
                                        (Token
                                          id: Id.Left_DollarParen
                                          val: '$('
                                          span_id: 1918
                                        )
                                      command_list: 
                                        (command.CommandList
                                          children: [(C {(id)} {(-u)})]
                                        )
                                    )
                                  } {(Id.Lit_Equals '=')} {(0)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:1929)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:CURRENTLY_UID_ZERO)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [1934]
                                )
                              ]
                            )
                          ]
                          spids: [1914 1931]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: disable_smtp_port_25_if_port_unavailable
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:PORT_25_AVAILABLE)
                          op: assign_op.Equal
                          rhs: {(DQ (no))}
                          spids: [1952]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: (C {(is_port_bound)} {(0.0.0.0)} {(25)})
                              terminator: (Token id:Id.Op_Semi val:';' span_id:1965)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:1970)
                            )
                          ]
                          spids: [1958 1967]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: (C {(is_port_bound)} {(127.0.0.1)} {(25)})
                              terminator: (Token id:Id.Op_Semi val:';' span_id:1983)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:1988)
                            )
                          ]
                          spids: [1976 1985]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:PORT_25_AVAILABLE)
                          op: assign_op.Equal
                          rhs: {(DQ (yes))}
                          spids: [1994]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: disable_https_if_ports_unavailable
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Id.Lit_VarLike 'PORT_80_AVAILABLE=') (DQ (no))})
                    (command.AndOr
                      ops: [Id.Op_DPipe]
                      children: [
                        (C {(is_port_bound)} {(0.0.0.0)} {(80)})
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:PORT_80_AVAILABLE)
                              op: assign_op.Equal
                              rhs: {(DQ (yes))}
                              spids: [2073]
                            )
                          ]
                        )
                      ]
                    )
                    (C {(local)} {(Id.Lit_VarLike 'PORT_443_AVAILABLE=') (DQ (no))})
                    (command.AndOr
                      ops: [Id.Op_DPipe]
                      children: [
                        (C {(is_port_bound)} {(0.0.0.0)} {(443)})
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:PORT_443_AVAILABLE)
                              op: assign_op.Equal
                              rhs: {(DQ (yes))}
                              spids: [2096]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {(DQ ($ Id.VSub_DollarName '$PORT_443_AVAILABLE'))} {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(DQ (no))} {(-o)} 
                                  {(DQ ($ Id.VSub_DollarName '$PORT_80_AVAILABLE'))} {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(DQ (no))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:2133)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDCATS_GETCERTIFICATE)
                                  op: assign_op.Equal
                                  rhs: {(DQ (no))}
                                  spids: [2138]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SHOW_MESSAGE_ABOUT_NEEDING_PORTS_OPEN)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [2144]
                                )
                              ]
                            )
                          ]
                          spids: [2103 2135]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: handle_args
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SCRIPT_NAME)
                          op: assign_op.Equal
                          rhs: {($ Id.VSub_Number '$1')}
                          spids: [2163]
                        )
                      ]
                    )
                    (C {(shift)})
                    (command.WhileUntil
                      keyword: (Token id:Id.KW_While val:while span_id:2171)
                      cond: [
                        (command.Sentence
                          child: (C {(getopts)} {(DQ (':deiup:'))} {(opt)})
                          terminator: (Token id:Id.Op_Semi val:';' span_id:2180)
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (command.Case
                              to_match: {($ Id.VSub_DollarName '$opt')}
                              arms: [
                                (case_arm
                                  pat_list: [{(d)}]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:USE_DEFAULTS)
                                          op: assign_op.Equal
                                          rhs: {(DQ (yes))}
                                          spids: [2196]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [2192 2193 2202 -1]
                                )
                                (case_arm
                                  pat_list: [{(e)}]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                          op: assign_op.Equal
                                          rhs: {(DQ (yes))}
                                          spids: [2209]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [2205 2206 2215 -1]
                                )
                                (case_arm
                                  pat_list: [{(i)}]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:SANDCATS_GETCERTIFICATE)
                                          op: assign_op.Equal
                                          rhs: {(DQ (no))}
                                          spids: [2222]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [2218 2219 2228 -1]
                                )
                                (case_arm
                                  pat_list: [{(u)}]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:PREFER_ROOT)
                                          op: assign_op.Equal
                                          rhs: {(no)}
                                          spids: [2235]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [2231 2232 2239 -1]
                                )
                                (case_arm
                                  pat_list: [{(p)}]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:DEFAULT_PORT)
                                          op: assign_op.Equal
                                          rhs: {(DQ (${ Id.VSub_Name OPTARG))}
                                          spids: [2246]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [2242 2243 2254 -1]
                                )
                                (case_arm
                                  pat_list: [{(Id.Lit_Star '*')}]
                                  action: [(C {(usage)})]
                                  spids: [2257 2258 2264 -1]
                                )
                              ]
                            )
                          ]
                        )
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:DEFAULT_PORT)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (DQ 
                                (braced_var_sub
                                  token: (Token id:Id.VSub_Name val:DEFAULT_PORT span_id:2281)
                                  suffix_op: 
                                    (suffix_op.Unary
                                      op_id: Id.VTest_ColonHyphen
                                      arg_word: {(6080)}
                                    )
                                )
                              )
                            }
                          spids: [2278]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:ORIGINAL_ARGS)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (sh_array_literal
                                left: (Token id:Id.Op_LParen val:'(' span_id:2298)
                                words: [{(DQ ($ Id.VSub_At '$@'))}]
                              )
                            }
                          spids: [2297]
                        )
                      ]
                    )
                    (C {(shift)} 
                      {
                        (DQ 
                          (word_part.ArithSub
                            anode: 
                              (arith_expr.Binary
                                op_id: Id.Arith_Minus
                                left: 
                                  (arith_expr.VarRef
                                    token: (Token id:Id.Lit_ArithVarLike val:OPTIND span_id:2314)
                                  )
                                right: (arith_expr.ArithWord w:{(Id.Lit_Digits 1)})
                              )
                          )
                        )
                      }
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Id.Op_DAmp]
                                  children: [
                                    (C {(Id.Lit_LBracket '[')} {($ Id.VSub_Pound '$#')} 
                                      {(Id.Lit_Equals '=')} {(1)} {(Id.Lit_RBracket ']')}
                                    )
                                    (command.DBracket
                                      expr: 
                                        (bool_expr.LogicalNot
                                          child: 
                                            (bool_expr.Binary
                                              op_id: Id.BoolBinary_EqualTilde
                                              left: {($ Id.VSub_Number '$1')}
                                              right: {(Id.Lit_Other '^') (-)}
                                            )
                                        )
                                    )
                                  ]
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:2351)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BUNDLE_FILE)
                                  op: assign_op.Equal
                                  rhs: {(DQ ($ Id.VSub_Number '$1'))}
                                  spids: [2356]
                                )
                              ]
                            )
                          ]
                          spids: [2325 2353]
                        )
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {($ Id.VSub_Pound '$#')} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(0)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:2374)
                            )
                          ]
                          action: [(C {(usage)})]
                          spids: [2362 2376]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: rerun_script_as_root
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} 
                      {(Id.Lit_VarLike 'ENVVARS=') 
                        (command_sub
                          left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:2431)
                          command_list: 
                            (command.CommandList
                              children: [(C {(echo)} {($ Id.VSub_At '$@')})]
                            )
                        )
                      }
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:ENVVARS)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (DQ ($ Id.VSub_DollarName '$ENVVARS') (' CURL_USER_AGENT=') 
                                ($ Id.VSub_DollarName '$CURL_USER_AGENT')
                              )
                            }
                          spids: [2447]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 2461
                                          )
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(basename)} {($ Id.VSub_DollarName '$SCRIPT_NAME')})
                                            ]
                                          )
                                      )
                                    )
                                  } {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(bash)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:2474)
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ('Re-running script as root...'))})
                            (C {(exec)} {(sudo)} {(bash)} {(-euo)} {(pipefail)} {(-c)} 
                              {
                                (DQ ('curl -fs -A ') ($ Id.VSub_DollarName '$CURL_USER_AGENT') 
                                  (' https://install.sandstorm.io | ') ($ Id.VSub_DollarName '$ENVVARS') (' bash')
                                )
                              }
                            )
                          ]
                          spids: [2456 2476]
                        )
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Id.Op_DAmp]
                                  children: [
                                    (C {(Id.Lit_LBracket '[')} 
                                      {
                                        (DQ 
                                          (command_sub
                                            left_token: 
                                              (Token
                                                id: Id.Left_DollarParen
                                                val: '$('
                                                span_id: 2517
                                              )
                                            command_list: 
                                              (command.CommandList
                                                children: [
                                                  (C {(basename)} 
                                                    {($ Id.VSub_DollarName '$SCRIPT_NAME')}
                                                  )
                                                ]
                                              )
                                          )
                                        )
                                      } {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(install.sh)} {(Id.Lit_RBracket ']')}
                                    )
                                    (C {(Id.Lit_LBracket '[')} {(-e)} {(DQ ($ Id.VSub_Number '$0'))} 
                                      {(Id.Lit_RBracket ']')}
                                    )
                                  ]
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:2542)
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ('Re-running script as root...'))})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} 
                                          {
                                            (braced_var_sub
                                              token: 
                                                (Token
                                                  id: Id.VSub_Name
                                                  val: ORIGINAL_ARGS
                                                  span_id: 2564
                                                )
                                              prefix_op: (Id.VSub_Pound)
                                              bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At)
                                            )
                                          } {(Id.Lit_Equals '=')} {(0)} {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:2575)
                                    )
                                  ]
                                  action: [
                                    (C {(exec)} {(sudo)} {($ Id.VSub_DollarName '$ENVVARS')} {(bash)} 
                                      {(DQ ($ Id.VSub_DollarName '$SCRIPT_NAME'))}
                                    )
                                  ]
                                  spids: [2558 2577]
                                )
                              ]
                              else_action: [
                                (C {(exec)} {(sudo)} {($ Id.VSub_DollarName '$ENVVARS')} {(bash)} 
                                  {(DQ ($ Id.VSub_DollarName '$SCRIPT_NAME'))} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:ORIGINAL_ARGS span_id:2610)
                                        bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At)
                                      )
                                    )
                                  }
                                )
                              ]
                            )
                          ]
                          spids: [2512 2544]
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(fail)}
                        {(DQ (E_CANT_SWITCH_TO_ROOT))}
                        {
                          (DQ 
                            (
'ERROR: This script could not detect its own filename, so could not switch to root. '
                            ) ("Please download a copy and name it 'install.sh' and run that as root, perhaps using sudo. ") 
                            ('Try this command:\n') ('\n') ('curl https://install.sandstorm.io/ > install.sh && sudo bash install.sh')
                          )
                        }
                      ]
                      more_env: [(env_pair name:REPORT val:{(no)} spids:[2629])]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: set_umask
              body: (command.BraceGroup children:[(C {(umask)} {(0022)})])
            )
            (command.ShFunction
              name: assert_on_terminal
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Id.Op_DAmp]
                                  children: [
                                    (C {(Id.Lit_LBracket '[')} {(DQ (no))} {(Id.Lit_Equals '=')} 
                                      {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {(Id.Lit_RBracket ']')}
                                    )
                                    (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-t)} {(1)} 
                                      {(Id.Lit_RBracket ']')}
                                    )
                                  ]
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:2703)
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [
                                {(fail)}
                                {(DQ (E_NO_TTY))}
                                {(DQ ('This script is interactive. Please run it on a terminal.'))}
                              ]
                              more_env: [(env_pair name:REPORT val:{(no)} spids:[2708])]
                            )
                          ]
                          spids: [2676 2705]
                        )
                      ]
                    )
                    (command.Simple
                      words: [{(exec)}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_LessAnd val:'3<&' span_id:2752)
                          fd: 3
                          arg_word: {(1)}
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: assert_linux_x86_64
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 2770
                                          )
                                        command_list: (command.CommandList children:[(C {(uname)})])
                                      )
                                    )
                                  } {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(Linux)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:2781)
                            )
                          ]
                          action: [
                            (C {(fail)} {(DQ (E_NON_LINUX))} 
                              {
                                (DQ 
                                  (
'Sandstorm requires Linux. If you want to run Sandstorm on a Windows or\n'
                                  ) ('Mac system, you can use Vagrant or another virtualization tool. See our install documentation:\n') 
                                  ('\n') ('- https://docs.sandstorm.io/en/latest/install/')
                                )
                              }
                            )
                          ]
                          spids: [2765 2783]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 2809
                                          )
                                        command_list: 
                                          (command.CommandList
                                            children: [(C {(uname)} {(-m)})]
                                          )
                                      )
                                    )
                                  } {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(x86_64)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:2822)
                            )
                          ]
                          action: [
                            (C {(fail)} {(DQ (E_NON_X86_64))} 
                              {
                                (DQ 
                                  (
'Sorry, the Sandstorm server currently only runs on x86_64 machines.'
                                  )
                                )
                              }
                            )
                          ]
                          spids: [2804 2824]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: assert_usable_kernel
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:KVERSION)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (sh_array_literal
                                left: (Token id:Id.Op_LParen val:'(' span_id:2851)
                                words: [
                                  {
                                    (command_sub
                                      left_token: 
                                        (Token
                                          id: Id.Left_DollarParen
                                          val: '$('
                                          span_id: 2853
                                        )
                                      command_list: 
                                        (command.CommandList
                                          children: [
                                            (command.Pipeline
                                              children: [
                                                (C {(uname)} {(-r)})
                                                (C {(grep)} {(-o)} 
                                                  {
                                                    (SQ 
                                                      (Token
                                                        id: Id.Lit_Chars
                                                        val: '^[0-9.]*'
                                                        span_id: 2865
                                                      )
                                                    )
                                                  }
                                                )
                                                (C {(tr)} {(.)} 
                                                  {(SQ (Token id:Id.Lit_Chars val:' ' span_id:2875))}
                                                )
                                              ]
                                              negated: F
                                            )
                                          ]
                                        )
                                    )
                                  }
                                ]
                              )
                            }
                          spids: [2850]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.DParen
                                  child: 
                                    (arith_expr.Binary
                                      op_id: Id.Arith_DPipe
                                      left: 
                                        (arith_expr.Binary
                                          op_id: Id.Arith_Less
                                          left: 
                                            (arith_expr.Binary
                                              op_id: Id.Arith_LBracket
                                              left: 
                                                (arith_expr.VarRef
                                                  token: 
                                                    (Token
                                                      id: Id.Lit_ArithVarLike
                                                      val: KVERSION
                                                      span_id: 2887
                                                    )
                                                )
                                              right: (arith_expr.ArithWord w:{(Id.Lit_Digits 0)})
                                            )
                                          right: (arith_expr.ArithWord w:{(Id.Lit_Digits 3)})
                                        )
                                      right: 
                                        (arith_expr.Binary
                                          op_id: Id.Arith_DAmp
                                          left: 
                                            (arith_expr.Binary
                                              op_id: Id.Arith_DEqual
                                              left: 
                                                (arith_expr.Binary
                                                  op_id: Id.Arith_LBracket
                                                  left: 
                                                    (arith_expr.VarRef
                                                      token: 
                                                        (Token
                                                          id: Id.Lit_ArithVarLike
                                                          val: KVERSION
                                                          span_id: 2899
                                                        )
                                                    )
                                                  right: (arith_expr.ArithWord w:{(Id.Lit_Digits 0)})
                                                )
                                              right: (arith_expr.ArithWord w:{(Id.Lit_Digits 3)})
                                            )
                                          right: 
                                            (arith_expr.Binary
                                              op_id: Id.Arith_Less
                                              left: 
                                                (arith_expr.Binary
                                                  op_id: Id.Arith_LBracket
                                                  left: 
                                                    (arith_expr.VarRef
                                                      token: 
                                                        (Token
                                                          id: Id.Lit_ArithVarLike
                                                          val: KVERSION
                                                          span_id: 2910
                                                        )
                                                    )
                                                  right: (arith_expr.ArithWord w:{(Id.Lit_Digits 1)})
                                                )
                                              right: (arith_expr.ArithWord w:{(Id.Lit_Digits 10)})
                                            )
                                        )
                                    )
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:2922)
                            )
                          ]
                          action: [
                            (C {(error)} 
                              {
                                (DQ ('Detected Linux kernel version: ') 
                                  (command_sub
                                    left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:2931)
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(uname)} {(-r)})]
                                      )
                                  )
                                )
                              }
                            )
                            (C {(fail)} {(DQ (E_KERNEL_OLDER_THAN_310))} 
                              {
                                (DQ 
                                  (
'Sorry, your kernel is too old to run Sandstorm. We require kernel'
                                  )
                                )
                              } {(DQ ('version 3.10 or newer.'))}
                            )
                          ]
                          spids: [2883 2924]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: maybe_enable_userns_sysctl
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:2994)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:3015)
                            )
                          ]
                          spids: [2977 2996]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (no))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3038)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:3047)
                            )
                          ]
                          spids: [3022 3040]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-e)} 
                                  {(/proc/sys/kernel/unprivileged_userns_clone)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3065)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:3074)
                            )
                          ]
                          spids: [3054 3067]
                        )
                      ]
                    )
                    (C {(local)} 
                      {(Id.Lit_VarLike 'OLD_VALUE=') 
                        (DQ 
                          (command_sub
                            left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:3085)
                            command_list: 
                              (command.CommandList
                                children: [
                                  (command.Simple
                                    redirects: [
                                      (redir.Redir
                                        op: (Token id:Id.Redir_Less val:'<' span_id:3086)
                                        fd: -1
                                        arg_word: {(/proc/sys/kernel/unprivileged_userns_clone)}
                                      )
                                    ]
                                  )
                                ]
                              )
                          )
                        )
                      }
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ ($ Id.VSub_DollarName '$OLD_VALUE'))} 
                                  {(Id.Lit_Equals '=')} {(DQ (1))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3109)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:3118)
                            )
                          ]
                          spids: [3094 3111]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Simple
                                  words: [
                                    {(sysctl)}
                                    {(-wq)}
                                    {(kernel.unprivileged_userns_clone) (Id.Lit_Equals '=') (1)}
                                  ]
                                  redirects: [
                                    (redir.Redir
                                      op: (Token id:Id.Redir_Great val:'2>' span_id:3139)
                                      fd: 2
                                      arg_word: {(/dev/null)}
                                    )
                                  ]
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3141)
                            )
                          ]
                          action: [
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'NOTE: Enabled unprivileged user namespaces because you passed -d.'
                                  )
                                )
                              }
                            )
                          ]
                          spids: [3129 3143]
                        )
                      ]
                      else_action: [
                        (command.ControlFlow
                          token: (Token id:Id.ControlFlow_Return val:return span_id:3160)
                        )
                      ]
                    )
                    (C {(local)} {(Id.Lit_VarLike 'SYSCTL_FILENAME=') (DQ (/etc/sysctl.conf))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-d)} {(/etc/sysctl.d)} 
                                  {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3193)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SYSCTL_FILENAME)
                                  op: assign_op.Equal
                                  rhs: {(DQ (/etc/sysctl.d/50-sandstorm.conf))}
                                  spids: [3198]
                                )
                              ]
                            )
                          ]
                          spids: [3183 3195]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Pipeline
                              children: [
                                (command.Simple
                                  words: [{(cat)}]
                                  redirects: [
                                    (redir.Redir
                                      op: (Token id:Id.Redir_DGreat val:'>>' span_id:3214)
                                      fd: -1
                                      arg_word: {(DQ ($ Id.VSub_DollarName '$SYSCTL_FILENAME'))}
                                    )
                                    (redir.HereDoc
                                      op: (Token id:Id.Redir_DLess val:'<<' span_id:3220)
                                      fd: -1
                                      here_begin: {(__EOF__)}
                                      here_end_span_id: 3228
                                      stdin_parts: [
                                        ('\n')
                                        (
'# Enable non-root users to create sandboxes (needed by Sandstorm).\n'
                                        )
                                        ('kernel.unprivileged_userns_clone = 1\n')
                                      ]
                                    )
                                  ]
                                )
                              ]
                              negated: T
                            )
                          ]
                          action: [
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
"NOTE: Never mind, not enabling userns because can't write /etc/sysctl.d."
                                  )
                                )
                              }
                            )
                            (command.AndOr
                              ops: [Id.Op_DPipe]
                              children: [
                                (C {(sysctl)} {(-wq)} 
                                  {
                                    (DQ ('kernel.unprivileged_userns_clone=') 
                                      ($ Id.VSub_DollarName '$OLD_VALUE')
                                    )
                                  }
                                )
                                (C {(true)})
                              ]
                            )
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:3266)
                            )
                          ]
                          spids: [3208 3230]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: test_if_dev_tcp_works
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Pipeline
                                  children: [
                                    (command.Subshell
                                      command_list: 
                                        (command.CommandList
                                          children: [
                                            (command.AndOr
                                              ops: [Id.Op_DPipe]
                                              children: [
                                                (command.Simple
                                                  words: [
                                                    {(timeout)}
                                                    {(1)}
                                                    {(bash)}
                                                    {(-c)}
                                                    {
                                                      (SQ 
                                                        (Token
                                                          id: Id.Lit_Chars
                                                          val: ': < /dev/tcp/localhost/0'
                                                          span_id: 3321
                                                        )
                                                      )
                                                    }
                                                  ]
                                                  redirects: [
                                                    (redir.Redir
                                                      op: 
                                                        (Token
                                                          id: Id.Redir_GreatAnd
                                                          val: '2>&'
                                                          span_id: 3324
                                                        )
                                                      fd: 2
                                                      arg_word: {(1)}
                                                    )
                                                  ]
                                                )
                                                (C {(true)})
                                              ]
                                            )
                                          ]
                                        )
                                    )
                                    (C {(grep)} {(-q)} 
                                      {(SQ (Token id:Id.Lit_Chars val:'connect:' span_id:3339))}
                                    )
                                  ]
                                  negated: F
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3342)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEV_TCP_USABLE)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [3355]
                                )
                              ]
                            )
                          ]
                          spids: [3309 3344]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:DEV_TCP_USABLE)
                              op: assign_op.Equal
                              rhs: {(DQ (no))}
                              spids: [3364]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: assert_dependencies
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:BUNDLE_FILE span_id:3390)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3396)
                            )
                          ]
                          action: [
                            (command.AndOr
                              ops: [Id.Op_DPipe]
                              children: [
                                (command.Simple
                                  words: [{(which)} {(curl)}]
                                  redirects: [
                                    (redir.Redir
                                      op: (Token id:Id.Redir_Great val:'>' span_id:3405)
                                      fd: -1
                                      arg_word: {(/dev/null)}
                                    )
                                  ]
                                )
                                (C {(fail)} {(DQ (E_CURL_MISSING))} 
                                  {
                                    (DQ 
                                      (
'Please install curl(1). Sandstorm uses it to download updates.'
                                      )
                                    )
                                  }
                                )
                              ]
                            )
                          ]
                          spids: [3382 3398]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (${ Id.VSub_Name DEV_TCP_USABLE))} 
                                  {(Id.Lit_Equals '=')} {(DQ (unchecked))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3451)
                            )
                          ]
                          action: [(C {(test_if_dev_tcp_works)})]
                          spids: [3433 3453]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (${ Id.VSub_Name DEV_TCP_USABLE))} 
                                  {(Id.Lit_Equals '=')} {(DQ (no))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3480)
                            )
                          ]
                          action: [
                            (command.AndOr
                              ops: [Id.Op_DPipe]
                              children: [
                                (command.Simple
                                  words: [{(which)} {(nc)}]
                                  redirects: [
                                    (redir.Redir
                                      op: (Token id:Id.Redir_Great val:'>' span_id:3489)
                                      fd: -1
                                      arg_word: {(/dev/null)}
                                    )
                                  ]
                                )
                                (C {(fail)} {(DQ (E_NC_MISSING))} 
                                  {
                                    (DQ 
                                      (
"Please install nc(1). (Package may be called 'netcat-traditional' or 'netcat-openbsd'.)"
                                      )
                                    )
                                  }
                                )
                              ]
                            )
                          ]
                          spids: [3462 3482]
                        )
                      ]
                    )
                    (command.AndOr
                      ops: [Id.Op_DPipe]
                      children: [
                        (command.Simple
                          words: [{(which)} {(tar)}]
                          redirects: [
                            (redir.Redir
                              op: (Token id:Id.Redir_Great val:'>' span_id:3514)
                              fd: -1
                              arg_word: {(/dev/null)}
                            )
                          ]
                        )
                        (C {(fail)} {(DQ (E_TAR_MISSING))} {(DQ ('Please install tar(1).'))})
                      ]
                    )
                    (command.AndOr
                      ops: [Id.Op_DPipe]
                      children: [
                        (command.Simple
                          words: [{(which)} {(xz)}]
                          redirects: [
                            (redir.Redir
                              op: (Token id:Id.Redir_Great val:'>' span_id:3535)
                              fd: -1
                              arg_word: {(/dev/null)}
                            )
                          ]
                        )
                        (C {(fail)} {(DQ (E_XZ_MISSING))} 
                          {(DQ ("Please install xz(1). (Package may be called 'xz-utils'.)"))}
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: assert_valid_bundle_file
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-n)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:BUNDLE_FILE span_id:3578)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3584)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BUNDLE_DIR)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 3598
                                          )
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (command.Pipeline
                                                children: [
                                                  (command.Subshell
                                                    command_list: 
                                                      (command.CommandList
                                                        children: [
                                                          (command.AndOr
                                                            ops: [Id.Op_DPipe]
                                                            children: [
                                                              (C {(tar)} {(Jtf)} 
                                                                {
                                                                  (DQ 
                                                                    ($ Id.VSub_DollarName 
'$BUNDLE_FILE'
                                                                    )
                                                                  )
                                                                }
                                                              )
                                                              (C {(true)})
                                                            ]
                                                          )
                                                        ]
                                                      )
                                                  )
                                                  (C {(head)} {(-n)} {(1)})
                                                ]
                                                negated: F
                                              )
                                            ]
                                          )
                                      )
                                    }
                                  spids: [3597]
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.DBracket
                                          expr: 
                                            (bool_expr.LogicalNot
                                              child: 
                                                (bool_expr.Binary
                                                  op_id: Id.BoolBinary_EqualTilde
                                                  left: {(DQ ($ Id.VSub_DollarName '$BUNDLE_DIR'))}
                                                  right: 
                                                    {(sandstorm-) (Id.Lit_Other '(') 
                                                      (Id.Lit_Other '[') (0-9) (Id.Lit_Other ']') (Id.Lit_Other '+') (Id.Lit_Other ')') (/)
                                                    }
                                                )
                                            )
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:3646)
                                    )
                                  ]
                                  action: [
                                    (C {(fail)} {(DQ (E_INVALID_BUNDLE))} 
                                      {
                                        (DQ ($ Id.VSub_DollarName '$BUNDLE_FILE') 
                                          (': Not a valid Sandstorm bundle')
                                        )
                                      }
                                    )
                                  ]
                                  spids: [3624 3648]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BUILD)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:BASH_REMATCH span_id:3669)
                                        bracket_op: 
                                          (bracket_op.ArrayIndex
                                            expr: (arith_expr.ArithWord w:{(Id.Lit_Digits 1)})
                                          )
                                      )
                                    }
                                  spids: [3667]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BUNDLE_FILE)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 3682
                                          )
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(readlink)} {(-f)} 
                                                {(DQ ($ Id.VSub_DollarName '$BUNDLE_FILE'))}
                                              )
                                            ]
                                          )
                                      )
                                    }
                                  spids: [3681]
                                )
                              ]
                            )
                          ]
                          spids: [3570 3586]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: detect_init_system
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:INIT_SYSTEM)
                          op: assign_op.Equal
                          rhs: {(DQ (unknown))}
                          spids: [3709]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: (C {(grep)} {(-q)} {(systemd)} {(/proc/1/comm)})
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3729)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:INIT_SYSTEM)
                                  op: assign_op.Equal
                                  rhs: {(DQ (systemd))}
                                  spids: [3734]
                                )
                              ]
                            )
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:3740)
                            )
                          ]
                          spids: [3720 3731]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-e)} {(/etc/init.d)} {(Id.Lit_RBracket ']')})
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3764)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:INIT_SYSTEM)
                                  op: assign_op.Equal
                                  rhs: {(DQ (sysvinit))}
                                  spids: [3769]
                                )
                              ]
                            )
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:3775)
                            )
                          ]
                          spids: [3755 3766]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_install_mode
              body: 
                (command.BraceGroup
                  children: [
                    (C {(echo)} {(-n)} 
                      {
                        (SQ 
                          (Token
                            id: Id.Lit_Chars
                            val: 'Sandstorm makes it easy to run web apps on your own server. '
                            span_id: 3804
                          )
                        )
                      }
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3825)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:CHOSEN_INSTALL_MODE)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: 
                                            (Token
                                              id: Id.VSub_Name
                                              val: CHOSEN_INSTALL_MODE
                                              span_id: 3833
                                            )
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: Id.VTest_ColonHyphen
                                              arg_word: {(2)}
                                            )
                                        )
                                      )
                                    }
                                  spids: [3830]
                                )
                              ]
                            )
                          ]
                          spids: [3809 3827]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (no))} {(Id.Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:PREFER_ROOT span_id:3859)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3866)
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'NOTE: Showing you all options, including development options, but omitting '
                                  )
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'      init script automation, because you chose to install without using root.'
                                  )
                                )
                              }
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:CHOSEN_INSTALL_MODE)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: 
                                            (Token
                                              id: Id.VSub_Name
                                              val: CHOSEN_INSTALL_MODE
                                              span_id: 3894
                                            )
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: Id.VTest_ColonHyphen
                                              arg_word: {(2)}
                                            )
                                        )
                                      )
                                    }
                                  spids: [3891]
                                )
                              ]
                            )
                          ]
                          spids: [3847 3868]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: 
                                          (Token
                                            id: Id.VSub_Name
                                            val: CHOSEN_INSTALL_MODE
                                            span_id: 3916
                                          )
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3922)
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ('You can have:'))})
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'1. A typical install, to use Sandstorm (press enter to accept this default)'
                                  )
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'2. A development server, for working on Sandstorm itself or localhost-based app development'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ )})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:CHOSEN_INSTALL_MODE)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 3961
                                          )
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(prompt-numeric)} 
                                                {
                                                  (DQ 
                                                    (
'How are you going to use this Sandstorm install?'
                                                    )
                                                  )
                                                } {(DQ (1))}
                                              )
                                            ]
                                          )
                                      )
                                    }
                                  spids: [3960]
                                )
                              ]
                            )
                          ]
                          spids: [3908 3924]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (1))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$CHOSEN_INSTALL_MODE'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:3994)
                            )
                          ]
                          action: [(C {(assert_full_server_dependencies)}) (C {(full_server_install)})]
                          spids: [3978 3996]
                        )
                      ]
                      else_action: [(C {(dev_server_install)})]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: assert_full_server_dependencies
              body: 
                (command.BraceGroup
                  children: [
                    (command.AndOr
                      ops: [Id.Op_DPipe]
                      children: [
                        (command.Simple
                          words: [{(which)} {(openssl)}]
                          redirects: [
                            (redir.Redir
                              op: (Token id:Id.Redir_Great val:'>' span_id:4039)
                              fd: -1
                              arg_word: {(/dev/null)}
                            )
                          ]
                        )
                        (C {(fail)} {(DQ (E_OPENSSL_MISSING))} 
                          {
                            (DQ 
                              (
'Please install openssl(1). Sandstorm uses it for the Sandcats.io dynamic DNS service.'
                              )
                            )
                          }
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: dev_server_install
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Id.Op_DAmp]
                                  children: [
                                    (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                      {(DQ ($ Id.VSub_DollarName '$PREFER_ROOT'))} {(Id.Lit_RBracket ']')}
                                    )
                                    (C {(Id.Lit_LBracket '[')} {(DQ (no))} {(Id.Lit_Equals '=')} 
                                      {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                    )
                                  ]
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:4137)
                            )
                          ]
                          action: [
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'If you want app developer mode for a Sandstorm install, you need root'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('due to limitations in the Linux kernel.'))})
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {(DQ ('To set up Sandstorm, we will use sudo to switch to root, then'))}
                            )
                            (C {(echo)} {(DQ ('provide further information before doing the install.'))})
                            (C {(echo)} 
                              {(DQ ("Sandstorm's database and web interface won't run as root."))}
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                          {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:4213)
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:ACCEPTED_SUDO_FOR_DEV_SERVER)
                                          op: assign_op.Equal
                                          rhs: {(DQ (no))}
                                          spids: [4218]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [4197 4215]
                                )
                              ]
                              else_action: [
                                (command.If
                                  arms: [
                                    (if_arm
                                      cond: [
                                        (command.Sentence
                                          child: 
                                            (C {(prompt-yesno)} {(DQ ('OK to continue?'))} {(DQ (yes))})
                                          terminator: (Token id:Id.Op_Semi val:';' span_id:4239)
                                        )
                                      ]
                                      action: [
                                        (command.ShAssignment
                                          pairs: [
                                            (assign_pair
                                              lhs: 
                                                (sh_lhs_expr.Name
                                                  name: ACCEPTED_SUDO_FOR_DEV_SERVER
                                                )
                                              op: assign_op.Equal
                                              rhs: {(DQ (yes))}
                                              spids: [4244]
                                            )
                                          ]
                                        )
                                      ]
                                      spids: [4227 4241]
                                    )
                                  ]
                                  else_action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:ACCEPTED_SUDO_FOR_DEV_SERVER)
                                          op: assign_op.Equal
                                          rhs: {(DQ (no))}
                                          spids: [4253]
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                          {
                                            (DQ 
                                              ($ Id.VSub_DollarName '$ACCEPTED_SUDO_FOR_DEV_SERVER')
                                            )
                                          } {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:4282)
                                    )
                                  ]
                                  action: [
                                    (C {(rerun_script_as_root)} 
                                      {(Id.Lit_VarLike 'CHOSEN_INSTALL_MODE=') (2)}
                                    )
                                  ]
                                  spids: [4266 4284]
                                )
                              ]
                              else_action: [
                                (command.Simple
                                  words: [
                                    {(fail)}
                                    {(DQ (E_NEED_ROOT))}
                                    {
                                      (DQ ('\n') 
                                        (
'One development feature does require root. To install anyway, run:\n'
                                        ) ('\n') ('install.sh -u\n') ('\n') 
                                        (
"to install without using root access. In that case, Sandstorm will operate OK but package tracing ('spk dev') will not work."
                                        )
                                      )
                                    }
                                  ]
                                  more_env: [
                                    (env_pair
                                      name: SHOW_FAILURE_MSG
                                      val: {(no)}
                                      spids: [4300]
                                    )
                                    (env_pair
                                      name: REPORT
                                      val: {(no)}
                                      spids: [4303]
                                    )
                                  ]
                                )
                              ]
                            )
                          ]
                          spids: [4105 4139]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Id.Op_DAmp]
                                  children: [
                                    (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                      {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {(Id.Lit_RBracket ']')}
                                    )
                                    (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                      {(DQ ($ Id.VSub_DollarName '$PREFER_ROOT'))} {(Id.Lit_RBracket ']')}
                                    )
                                  ]
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:4382)
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ("We're going to:"))})
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ ('* Install Sandstorm in ') (${ Id.VSub_Name DEFAULT_DIR_FOR_ROOT) 
                                  (.)
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'* Automatically keep Sandstorm up-to-date (with signed updates).'
                                  )
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ ('* Create a service user (') 
                                  ($ Id.VSub_DollarName '$DEFAULT_SERVER_USER') (") that owns Sandstorm's files.")
                                )
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(-n)} 
                                          {
                                            (DQ 
                                              (braced_var_sub
                                                token: 
                                                  (Token
                                                    id: Id.VSub_Name
                                                    val: SUDO_USER
                                                    span_id: 4435
                                                  )
                                                suffix_op: 
                                                  (suffix_op.Unary
                                                    op_id: Id.VTest_ColonHyphen
                                                    arg_word: (word.Empty)
                                                  )
                                              )
                                            )
                                          } {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:4441)
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} 
                                      {
                                        (DQ ('* Add you (') ($ Id.VSub_DollarName '$SUDO_USER') 
                                          (') to the ') ($ Id.VSub_DollarName '$DEFAULT_SERVER_USER') (' group so you can read/write app data.')
                                        )
                                      }
                                    )
                                  ]
                                  spids: [4427 4443]
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'* Expose the service only on localhost aka local.sandstorm.io, not the public Internet.'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ("* Enable 'dev accounts', for easy developer login."))})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(DQ (unknown))} 
                                          {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$INIT_SYSTEM'))} {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:4490)
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'*** WARNING: Could not detect how to run Sandstorm at startup on your system. ***'
                                          )
                                        )
                                      }
                                    )
                                  ]
                                  spids: [4474 4492]
                                )
                              ]
                              else_action: [
                                (C {(echo)} 
                                  {
                                    (DQ ('* Configure Sandstorm to start on system boot (with ') 
                                      ($ Id.VSub_DollarName '$INIT_SYSTEM') (').')
                                    )
                                  }
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('* Listen for inbound email on port ') 
                                  (${ Id.VSub_Name DEFAULT_SMTP_PORT) (.)
                                )
                              }
                            )
                            (C {(echo)} {(DQ )})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} 
                                          {
                                            (DQ 
                                              (
"Press enter to accept defaults. Type 'no' to customize."
                                              )
                                            )
                                          } {(DQ (yes))}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:4547)
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:USE_DEFAULTS)
                                          op: assign_op.Equal
                                          rhs: {(DQ (yes))}
                                          spids: [4552]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [4535 4549]
                                )
                              ]
                              else_action: [
                                (C {(echo)} {(DQ )})
                                (C {(echo)} {(DQ ('OK. We will prompt you with every question.'))})
                                (C {(echo)} {(DQ )})
                              ]
                            )
                          ]
                          spids: [4349 4384]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:4604)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL)
                                  op: assign_op.Equal
                                  rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_UPDATE_CHANNEL'))}
                                  spids: [4613]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: 
                                            (Token
                                              id: Id.VSub_Name
                                              val: USE_EXTERNAL_INTERFACE
                                              span_id: 4627
                                            )
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: Id.VTest_ColonHyphen
                                              arg_word: {(no)}
                                            )
                                        )
                                      )
                                    }
                                  spids: [4624]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: (Token id:Id.VSub_Name val:SS_HOSTNAME span_id:4650)
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: Id.VTest_ColonHyphen
                                              arg_word: {(local.sandstorm.io)}
                                            )
                                        )
                                      )
                                    }
                                  spids: [4647]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SMTP_LISTEN_PORT)
                                  op: assign_op.Equal
                                  rhs: {(DQ (${ Id.VSub_Name DEFAULT_SMTP_PORT))}
                                  spids: [4662]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:START_AT_BOOT)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [4675]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_SANDCATS)
                                  op: assign_op.Equal
                                  rhs: {(DQ (no))}
                                  spids: [4686]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:PORT)
                                  op: assign_op.Equal
                                  rhs: {(DQ (${ Id.VSub_Name DEFAULT_PORT))}
                                  spids: [4697]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:ALLOW_DEV_ACCOUNTS)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [4719]
                                )
                              ]
                            )
                          ]
                          spids: [4588 4606]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: full_server_install
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ (${ Id.VSub_Name PREFER_ROOT))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:4802)
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [
                                {(fail)}
                                {(DQ (E_AUTO_NEEDS_SUDO))}
                                {
                                  (DQ 
                                    (
'The automatic setup process requires sudo. Try again with option 2, development server, to customize.'
                                    )
                                  )
                                }
                              ]
                              more_env: [(env_pair name:REPORT val:{(no)} spids:[4807])]
                            )
                          ]
                          spids: [4783 4804]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:4841)
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(-z)} 
                                          {
                                            (DQ 
                                              (braced_var_sub
                                                token: 
                                                  (Token
                                                    id: Id.VSub_Name
                                                    val: DESIRED_SANDCATS_NAME
                                                    span_id: 4854
                                                  )
                                                suffix_op: (suffix_op.Unary op_id:Id.VTest_Hyphen arg_word:(word.Empty))
                                              )
                                            )
                                          } {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:4861)
                                    )
                                  ]
                                  action: [
                                    (C {(local)} 
                                      {(Id.Lit_VarLike 'MSG=') 
                                        (DQ 
                                          (
'For now, USE_DEFAULTS for full server installs requires a DESIRED_SANDCATS_NAME variable.'
                                          )
                                        )
                                      }
                                    )
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:MSG)
                                          op: assign_op.Equal
                                          rhs: 
                                            {
                                              (DQ ($ Id.VSub_DollarName '$MSG') 
                                                (
' If you need support for non-sandcats full-server unattended installs, please file a bug.'
                                                )
                                              )
                                            }
                                          spids: [4874]
                                        )
                                      ]
                                    )
                                    (C {(fail)} {(DQ (E_USE_DEFAULTS_NEEDS_DESIRED_SANDCATS_NAME))} 
                                      {(DQ ($ Id.VSub_DollarName '$MSG'))}
                                    )
                                  ]
                                  spids: [4846 4863]
                                )
                              ]
                              else_action: [
                                (command.If
                                  arms: [
                                    (if_arm
                                      cond: [
                                        (command.Sentence
                                          child: 
                                            (C {(Id.Lit_LBracket '[')} {(-z)} 
                                              {
                                                (DQ 
                                                  (braced_var_sub
                                                    token: 
                                                      (Token
                                                        id: Id.VSub_Name
                                                        val: SANDCATS_DOMAIN_RESERVATION_TOKEN
                                                        span_id: 4903
                                                      )
                                                    suffix_op: 
                                                      (suffix_op.Unary
                                                        op_id: Id.VTest_ColonHyphen
                                                        arg_word: (word.Empty)
                                                      )
                                                  )
                                                )
                                              } {(Id.Lit_RBracket ']')}
                                            )
                                          terminator: (Token id:Id.Op_Semi val:';' span_id:4910)
                                        )
                                      ]
                                      action: [
                                        (C {(local)} 
                                          {(Id.Lit_VarLike 'MSG=') 
                                            (DQ 
                                              (
'When operating in USE_DEFAULTS mode, if you want a sandcats.io domain,'
                                              )
                                            )
                                          }
                                        )
                                        (command.ShAssignment
                                          pairs: [
                                            (assign_pair
                                              lhs: (sh_lhs_expr.Name name:MSG)
                                              op: assign_op.Equal
                                              rhs: 
                                                {
                                                  (DQ ($ Id.VSub_DollarName '$MSG') 
                                                    (
' you must pre-reserve it before running this script. Specify it via the'
                                                    )
                                                  )
                                                }
                                              spids: [4923]
                                            )
                                          ]
                                        )
                                        (command.ShAssignment
                                          pairs: [
                                            (assign_pair
                                              lhs: (sh_lhs_expr.Name name:MSG)
                                              op: assign_op.Equal
                                              rhs: 
                                                {
                                                  (DQ ($ Id.VSub_DollarName '$MSG') 
                                                    (
' SANDCATS_DOMAIN_RESERVATION_TOKEN environment variable.'
                                                    )
                                                  )
                                                }
                                              spids: [4930]
                                            )
                                          ]
                                        )
                                        (C {(fail)} {(DQ (E_USE_DEFAULTS_NEEDS_DESIRED_SANDCATS_NAME))} 
                                          {(DQ ($ Id.VSub_DollarName '$MSG'))}
                                        )
                                      ]
                                      spids: [4895 4912]
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:ACCEPTED_FULL_SERVER_INSTALL)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [4959]
                                )
                              ]
                            )
                          ]
                          spids: [4825 4843]
                        )
                      ]
                    )
                    (C {(disable_smtp_port_25_if_port_unavailable)})
                    (C {(local)} {(Id.Lit_VarLike 'PLANNED_SMTP_PORT=') (DQ (30025))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$PORT_25_AVAILABLE'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:5000)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:PLANNED_SMTP_PORT)
                                  op: assign_op.Equal
                                  rhs: {(DQ (25))}
                                  spids: [5005]
                                )
                              ]
                            )
                          ]
                          spids: [4984 5002]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: 
                                          (Token
                                            id: Id.VSub_Name
                                            val: ACCEPTED_FULL_SERVER_INSTALL
                                            span_id: 5028
                                          )
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:5034)
                            )
                          ]
                          action: [
                            (C {(disable_https_if_ports_unavailable)})
                            (C {(echo)} {(DQ ("We're going to:"))})
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ ('* Install Sandstorm in ') 
                                  ($ Id.VSub_DollarName '$DEFAULT_DIR_FOR_ROOT')
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('* Automatically keep Sandstorm up-to-date'))})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                          {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$SANDCATS_GETCERTIFICATE'))} {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:5092)
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'* Configure auto-renewing HTTPS if you use a subdomain of sandcats.io'
                                          )
                                        )
                                      }
                                    )
                                  ]
                                  spids: [5075 5094]
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('* Create a service user (') 
                                  ($ Id.VSub_DollarName '$DEFAULT_SERVER_USER') (") that owns Sandstorm's files")
                                )
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(DQ (unknown))} 
                                          {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$INIT_SYSTEM'))} {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:5132)
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'*** WARNING: Could not detect how to run Sandstorm at startup on your system. ***'
                                          )
                                        )
                                      }
                                    )
                                  ]
                                  spids: [5116 5134]
                                )
                              ]
                              else_action: [
                                (C {(echo)} 
                                  {
                                    (DQ ('* Configure Sandstorm to start on system boot (with ') 
                                      ($ Id.VSub_DollarName '$INIT_SYSTEM') (')')
                                    )
                                  }
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('* Listen for inbound email on port ') 
                                  (${ Id.VSub_Name PLANNED_SMTP_PORT) (.)
                                )
                              }
                            )
                            (C {(echo)} {(DQ )})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                          {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:5197)
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} 
                                      {(DQ ('To set up Sandstorm, we will need to use sudo.'))}
                                    )
                                  ]
                                  spids: [5181 5199]
                                )
                              ]
                              else_action: [
                                (C {(echo)} 
                                  {(DQ ("Rest assured that Sandstorm itself won't run as root."))}
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} {(DQ ('OK to continue?'))} {(DQ (yes))})
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:5234)
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:ACCEPTED_FULL_SERVER_INSTALL)
                                          op: assign_op.Equal
                                          rhs: {(yes)}
                                          spids: [5239]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [5223 5236]
                                )
                              ]
                              else_action: [
                                (command.ShAssignment
                                  pairs: [
                                    (assign_pair
                                      lhs: (sh_lhs_expr.Name name:ACCEPTED_FULL_SERVER_INSTALL)
                                      op: assign_op.Equal
                                      rhs: {(no)}
                                      spids: [5246]
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                          {
                                            (DQ 
                                              ($ Id.VSub_DollarName 
'$SHOW_MESSAGE_ABOUT_NEEDING_PORTS_OPEN'
                                              )
                                            )
                                          } {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:5270)
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} {(DQ )})
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'NOTE: It looks like your system already has some other web server installed'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'      (port 80 and/or 443 are taken), so Sandstorm cannot act as your main'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} {(DQ ('      web server.'))})
                                    (C {(echo)} {(DQ )})
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          ('      This script can set up Sandstorm to run on port ') ($ Id.VSub_DollarName '$DEFAULT_PORT') (' instead,')
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
"      without HTTPS. This makes sense if you're OK with typing the port number"
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
"      into your browser whenever you access Sandstorm and you don't need"
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'      security. This also makes sense if you are going to set up a reverse proxy;'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'      if so, see https://docs.sandstorm.io/en/latest/administering/reverse-proxy/'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} {(DQ )})
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'      If you want, you can quit this script with Ctrl-C now, and go uninstall'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'      your other web server, and then run this script again. It is also OK to'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} {(DQ ('      proceed if you want.'))})
                                    (C {(echo)} {(DQ )})
                                    (command.If
                                      arms: [
                                        (if_arm
                                          cond: [
                                            (command.Sentence
                                              child: 
                                                (command.Pipeline
                                                  children: [
                                                    (C {(prompt-yesno)} 
                                                      {
                                                        (DQ 
                                                          (
'OK to skip automatic HTTPS setup & bind to port '
                                                          ) ($ Id.VSub_DollarName '$DEFAULT_PORT') (' instead?')
                                                        )
                                                      } {(DQ (yes))}
                                                    )
                                                  ]
                                                  negated: T
                                                )
                                              terminator: (Token id:Id.Op_Semi val:';' span_id:5394)
                                            )
                                          ]
                                          action: [
                                            (C {(fail)} {(DQ (E_USER_REFUSED_DEFAULT_PORT))} 
                                              {
                                                (DQ 
                                                  (
'Exiting now. You can re-run the installer whenever you are ready.'
                                                  )
                                                )
                                              }
                                            )
                                          ]
                                          spids: [5378 5396]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [5254 5272]
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                          {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:5458)
                                    )
                                  ]
                                  action: [
                                    (command.If
                                      arms: [
                                        (if_arm
                                          cond: [
                                            (command.Sentence
                                              child: 
                                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                                  {(Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$ACCEPTED_FULL_SERVER_INSTALL'))} {(Id.Lit_RBracket ']')}
                                                )
                                              terminator: (Token id:Id.Op_Semi val:';' span_id:5479)
                                            )
                                          ]
                                          action: [
                                            (C {(rerun_script_as_root)} 
                                              {(Id.Lit_VarLike 'CHOSEN_INSTALL_MODE=') (1)} {(Id.Lit_VarLike 'ACCEPTED_FULL_SERVER_INSTALL=') (yes)} 
                                              {(Id.Lit_VarLike 'OVERRIDE_SANDCATS_BASE_DOMAIN=') 
                                                (DQ 
                                                  (braced_var_sub
                                                    token: 
                                                      (Token
                                                        id: Id.VSub_Name
                                                        val: OVERRIDE_SANDCATS_BASE_DOMAIN
                                                        span_id: 5499
                                                      )
                                                    suffix_op: 
                                                      (suffix_op.Unary
                                                        op_id: Id.VTest_ColonHyphen
                                                        arg_word: (word.Empty)
                                                      )
                                                  )
                                                )
                                              } 
                                              {(Id.Lit_VarLike 'OVERRIDE_SANDCATS_API_BASE=') 
                                                (DQ 
                                                  (braced_var_sub
                                                    token: 
                                                      (Token
                                                        id: Id.VSub_Name
                                                        val: OVERRIDE_SANDCATS_API_BASE
                                                        span_id: 5509
                                                      )
                                                    suffix_op: 
                                                      (suffix_op.Unary
                                                        op_id: Id.VTest_ColonHyphen
                                                        arg_word: (word.Empty)
                                                      )
                                                  )
                                                )
                                              } {(Id.Lit_VarLike 'OVERRIDE_SANDCATS_GETCERTIFICATE=') (DQ (${ Id.VSub_Name SANDCATS_GETCERTIFICATE))} 
                                              {(Id.Lit_VarLike 'OVERRIDE_NC_PATH=') 
                                                (DQ 
                                                  (braced_var_sub
                                                    token: 
                                                      (Token
                                                        id: Id.VSub_Name
                                                        val: OVERRIDE_NC_PATH
                                                        span_id: 5528
                                                      )
                                                    suffix_op: 
                                                      (suffix_op.Unary
                                                        op_id: Id.VTest_ColonHyphen
                                                        arg_word: (word.Empty)
                                                      )
                                                  )
                                                )
                                              } 
                                              {(Id.Lit_VarLike 'OVERRIDE_SANDCATS_CURL_PARAMS=') 
                                                (DQ 
                                                  (braced_var_sub
                                                    token: 
                                                      (Token
                                                        id: Id.VSub_Name
                                                        val: OVERRIDE_SANDCATS_CURL_PARAMS
                                                        span_id: 5538
                                                      )
                                                    suffix_op: 
                                                      (suffix_op.Unary
                                                        op_id: Id.VTest_ColonHyphen
                                                        arg_word: (word.Empty)
                                                      )
                                                  )
                                                )
                                              }
                                            )
                                          ]
                                          spids: [5463 5481]
                                        )
                                      ]
                                    )
                                    (C {(echo)} {(DQ )})
                                    (C {(echo)} 
                                      {(DQ ('The automatic setup script needs root in order to:'))}
                                    )
                                    (C {(echo)} 
                                      {(DQ ('* Create a separate user to run Sandstorm as, and'))}
                                    )
                                    (C {(echo)} {(DQ ('* Set up Sandstorm to start on system boot.'))})
                                    (C {(fail)} {(DQ (E_DECLINED_AUTO_SETUP_DETAILS))} 
                                      {
                                        (DQ 
                                          (
'For a customized install, please re-run install.sh, and choose option (2) '
                                          )
                                        )
                                      } {(DQ ('to do a development install.'))}
                                    )
                                  ]
                                  spids: [5441 5460]
                                )
                              ]
                            )
                          ]
                          spids: [5015 5036]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ (${ Id.VSub_Name ACCEPTED_FULL_SERVER_INSTALL))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:5623)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL)
                                  op: assign_op.Equal
                                  rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_UPDATE_CHANNEL'))}
                                  spids: [5628]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DIR)
                                  op: assign_op.Equal
                                  rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_DIR_FOR_ROOT'))}
                                  spids: [5634]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [5640]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_SANDCATS)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [5646]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:START_AT_BOOT)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [5652]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DESIRED_SERVER_USER)
                                  op: assign_op.Equal
                                  rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_SERVER_USER'))}
                                  spids: [5658]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:PORT)
                                  op: assign_op.Equal
                                  rhs: {(DQ (${ Id.VSub_Name DEFAULT_PORT))}
                                  spids: [5664]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:MONGO_PORT)
                                  op: assign_op.Equal
                                  rhs: {(DQ (6081))}
                                  spids: [5672]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SMTP_LISTEN_PORT)
                                  op: assign_op.Equal
                                  rhs: {(DQ (${ Id.VSub_Name PLANNED_SMTP_PORT))}
                                  spids: [5678]
                                )
                              ]
                            )
                          ]
                          spids: [5606 5625]
                        )
                      ]
                      else_action: [
                        (command.Simple
                          words: [
                            {(fail)}
                            {(DQ (E_USER_WANTS_CUSTOM_SETTINGS))}
                            {
                              (DQ 
                                (
'If you prefer a more manual setup experience, try installing in development mode.'
                                )
                              )
                            }
                          ]
                          more_env: [(env_pair name:REPORT val:{(no)} spids:[5689])]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_configure
              body: 
                (command.BraceGroup
                  children: [
                    (C {(echo)} {(-n)} 
                      {(DQ ('As a Sandstorm user, you are invited to use a free Internet hostname '))}
                    )
                    (C {(echo)} {(DQ ('as a subdomain of sandcats.io,'))})
                    (C {(echo)} {(DQ ('a service operated by the Sandstorm development team.'))})
                    (C {(sandcats_generate_keys)})
                    (C {(echo)} {(DQ )})
                    (C {(echo)} 
                      {
                        (DQ 
                          (
'Sandcats.io protects your privacy and is subject to terms of use. By using it,'
                          )
                        )
                      }
                    )
                    (C {(echo)} 
                      {(DQ ('you agree to the terms of service & privacy policy available here:'))}
                    )
                    (C {(echo)} {(DQ ('https://sandcats.io/terms https://sandcats.io/privacy'))})
                    (C {(echo)} {(DQ )})
                    (C {(sandcats_register_name)})
                    (C {(sandcats_configure_https)})
                  ]
                )
            )
            (command.ShFunction
              name: configure_hostnames
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$USE_SANDCATS'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:5849)
                            )
                          ]
                          action: [(C {(sandcats_configure)})]
                          spids: [5833 5851]
                        )
                      ]
                    )
                    (C {(choose_port)})
                    (C {(choose_mongo_port)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$USE_EXTERNAL_INTERFACE'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:5915)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BIND_IP)
                                  op: assign_op.Equal
                                  rhs: {(0.0.0.0)}
                                  spids: [5920]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: (Token id:Id.VSub_Name val:SS_HOSTNAME span_id:5927)
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: Id.VTest_ColonHyphen
                                              arg_word: 
                                                {
                                                  (command_sub
                                                    left_token: 
                                                      (Token
                                                        id: Id.Left_DollarParen
                                                        val: '$('
                                                        span_id: 5929
                                                      )
                                                    command_list: 
                                                      (command.CommandList
                                                        children: [
                                                          (command.AndOr
                                                            ops: [Id.Op_DPipe]
                                                            children: [
                                                              (command.Simple
                                                                words: [{(hostname)} {(-f)}]
                                                                redirects: [
                                                                  (redir.Redir
                                                                    op: 
                                                                      (Token
                                                                        id: Id.Redir_Great
                                                                        val: '2>'
                                                                        span_id: 5934
                                                                      )
                                                                    fd: 2
                                                                    arg_word: {(/dev/null)}
                                                                  )
                                                                ]
                                                              )
                                                              (C {(hostname)})
                                                            ]
                                                          )
                                                        ]
                                                      )
                                                  )
                                                }
                                            )
                                        )
                                      )
                                    }
                                  spids: [5924]
                                )
                              ]
                            )
                          ]
                          spids: [5900 5917]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:BIND_IP)
                              op: assign_op.Equal
                              rhs: {(127.0.0.1)}
                              spids: [5948]
                            )
                          ]
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                              op: assign_op.Equal
                              rhs: {(local.sandstorm.io)}
                              spids: [5952]
                            )
                          ]
                        )
                        (command.If
                          arms: [
                            (if_arm
                              cond: [
                                (command.Sentence
                                  child: 
                                    (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                      {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {(Id.Lit_RBracket ']')}
                                    )
                                  terminator: (Token id:Id.Op_Semi val:';' span_id:5973)
                                )
                              ]
                              action: [
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'Note: local.sandstorm.io maps to 127.0.0.1, i.e. your local machine.'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'For reasons that will become clear in the next step, you should use this'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} {(DQ ("instead of 'localhost'."))})
                              ]
                              spids: [5956 5975]
                            )
                          ]
                        )
                      ]
                    )
                    (C {(local)} {(Id.Lit_VarLike 'PORT_SUFFIX=') (DQ )})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ ($ Id.VSub_DollarName '$PORT'))} 
                                  {(Id.Lit_Equals '=')} {(DQ (80))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:6041)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:PORT_SUFFIX)
                                  op: assign_op.Equal
                                  rhs: {(DQ )}
                                  spids: [6046]
                                )
                              ]
                            )
                          ]
                          spids: [6025 6043]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:PORT_SUFFIX)
                              op: assign_op.Equal
                              rhs: {(DQ (':') (${ Id.VSub_Name PORT))}
                              spids: [6054]
                            )
                          ]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:DEFAULT_BASE_URL)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (DQ ('http://') (${ Id.VSub_Name SS_HOSTNAME) 
                                (${ Id.VSub_Name PORT_SUFFIX)
                              )
                            }
                          spids: [6067]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {(DQ ($ Id.VSub_DollarName '$SANDCATS_HTTPS_SUCCESSFUL'))} {(Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:6099)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEFAULT_BASE_URL)
                                  op: assign_op.Equal
                                  rhs: {(DQ ('https://') ($ Id.VSub_DollarName '$SS_HOSTNAME'))}
                                  spids: [6104]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:HTTPS_PORT)
                                  op: assign_op.Equal
                                  rhs: {(443)}
                                  spids: [6111]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:PORT)
                                  op: assign_op.Equal
                                  rhs: {(80)}
                                  spids: [6115]
                                )
                              ]
                            )
                          ]
                          spids: [6084 6101]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:6139)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BASE_URL)
                                  op: assign_op.Equal
                                  rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_BASE_URL'))}
                                  spids: [6152]
                                )
                              ]
                            )
                          ]
                          spids: [6123 6141]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:BASE_URL)
                              op: assign_op.Equal
                              rhs: 
                                {
                                  (command_sub
                                    left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:6162)
                                    command_list: 
                                      (command.CommandList
                                        children: [
                                          (C {(prompt)} {(DQ ('URL users will enter in browser:'))} 
                                            {(DQ ($ Id.VSub_DollarName '$DEFAULT_BASE_URL'))}
                                          )
                                        ]
                                      )
                                  )
                                }
                              spids: [6161]
                            )
                          ]
                        )
                        (command.If
                          arms: [
                            (if_arm
                              cond: [
                                (command.Sentence
                                  child: 
                                    (command.Pipeline
                                      children: [
                                        (command.DBracket
                                          expr: 
                                            (bool_expr.Binary
                                              op_id: Id.BoolBinary_EqualTilde
                                              left: {(DQ ($ Id.VSub_DollarName '$BASE_URL'))}
                                              right: 
                                                {(Id.Lit_Other '^') (http) (Id.Lit_Other '(') (s) 
                                                  (Id.Lit_Other '?') (Id.Lit_Other ')') (Id.Lit_Other ':') (//)
                                                }
                                            )
                                        )
                                      ]
                                      negated: T
                                    )
                                  terminator: (Token id:Id.Op_Semi val:';' span_id:6198)
                                )
                              ]
                              action: [
                                (C {(local)} 
                                  {(Id.Lit_VarLike 'PROPOSED_BASE_URL=') 
                                    (DQ ('http://') (${ Id.VSub_Name BASE_URL))
                                  }
                                )
                                (command.Simple
                                  words: [
                                    {(echo)}
                                    {
                                      (DQ ('** You entered ') (${ Id.VSub_Name BASE_URL) 
                                        (', which needs http:// at the front. I can use:')
                                      )
                                    }
                                  ]
                                  redirects: [
                                    (redir.Redir
                                      op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:6224)
                                      fd: -1
                                      arg_word: {(2)}
                                    )
                                  ]
                                )
                                (command.Simple
                                  words: [
                                    {(echo)}
                                    {(DQ ('        ') (${ Id.VSub_Name PROPOSED_BASE_URL))}
                                  ]
                                  redirects: [
                                    (redir.Redir
                                      op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:6237)
                                      fd: -1
                                      arg_word: {(2)}
                                    )
                                  ]
                                )
                                (command.If
                                  arms: [
                                    (if_arm
                                      cond: [
                                        (command.Sentence
                                          child: (C {(prompt-yesno)} {(DQ ('Is this OK?'))} {(yes)})
                                          terminator: (Token id:Id.Op_Semi val:';' span_id:6250)
                                        )
                                      ]
                                      action: [
                                        (command.ShAssignment
                                          pairs: [
                                            (assign_pair
                                              lhs: (sh_lhs_expr.Name name:BASE_URL)
                                              op: assign_op.Equal
                                              rhs: {(DQ (${ Id.VSub_Name PROPOSED_BASE_URL))}
                                              spids: [6255]
                                            )
                                          ]
                                        )
                                      ]
                                      spids: [6241 6252]
                                    )
                                  ]
                                  else_action: [(C {(configure_hostnames)})]
                                )
                              ]
                              spids: [6175 6200]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.DBracket
                                  expr: 
                                    (bool_expr.Binary
                                      op_id: Id.BoolBinary_EqualTilde
                                      left: {(DQ ($ Id.VSub_DollarName '$BASE_URL'))}
                                      right: 
                                        {(Id.Lit_Other '^') (http) (Id.Lit_Other ':') (//localhost) 
                                          (Id.Lit_Other '(') (Id.Lit_Other '|') (Id.Lit_Other ':') (Id.Lit_Other '[') (0-9) (Id.Lit_Other ']') (Id.Lit_Other '*') 
                                          (Id.Lit_Other ')') (Id.Lit_Other '(') (/) (Id.Lit_Other .) (Id.Lit_Other '*') (Id.Lit_Other ')') (Id.Lit_Other '?') 
                                          (Id.Lit_Other '$')
                                        }
                                    )
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:6318)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEFAULT_WILDCARD)
                                  op: assign_op.Equal
                                  rhs: 
                                    {(Id.Lit_Star '*') (.local.sandstorm.io) 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:BASH_REMATCH span_id:6327)
                                        bracket_op: 
                                          (bracket_op.ArrayIndex
                                            expr: (arith_expr.ArithWord w:{(Id.Lit_Digits 1)})
                                          )
                                      )
                                    }
                                  spids: [6323]
                                )
                              ]
                            )
                          ]
                          spids: [6287 6320]
                        )
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.DBracket
                                  expr: 
                                    (bool_expr.Binary
                                      op_id: Id.BoolBinary_EqualTilde
                                      left: {(DQ ($ Id.VSub_DollarName '$BASE_URL'))}
                                      right: 
                                        {(Id.Lit_Other '^') (Id.Lit_Other '[') (Id.Lit_Other '^') 
                                          (Id.Lit_Other ':') (/) (Id.Lit_Other ']') (Id.Lit_Other '*') (Id.Lit_Other ':') (//) (Id.Lit_Other '(') (Id.Lit_Other '[') 
                                          (Id.Lit_Other '^') (/) (Id.Lit_Other ']') (Id.Lit_Other '*') (Id.Lit_Other ')') (/) (Id.Lit_Other '?') (Id.Lit_Other '$')
                                        }
                                    )
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:6365)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEFAULT_WILDCARD)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: 
                                            (Token
                                              id: Id.VSub_Name
                                              val: DEFAULT_WILDCARD
                                              span_id: 6373
                                            )
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: Id.VTest_ColonHyphen
                                              arg_word: 
                                                {('*.') 
                                                  (braced_var_sub
                                                    token: 
                                                      (Token
                                                        id: Id.VSub_Name
                                                        val: BASH_REMATCH
                                                        span_id: 6377
                                                      )
                                                    bracket_op: 
                                                      (bracket_op.ArrayIndex
                                                        expr: 
                                                          (arith_expr.ArithWord
                                                            w: {(Id.Lit_Digits 1)}
                                                          )
                                                      )
                                                  )
                                                }
                                            )
                                        )
                                      )
                                    }
                                  spids: [6370]
                                )
                              ]
                            )
                          ]
                          spids: [6334 6367]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:DEFAULT_WILDCARD)
                              op: assign_op.Equal
                              rhs: (word.Empty)
                              spids: [6389]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:6420)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:WILDCARD_HOST)
                                  op: assign_op.Equal
                                  rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_WILDCARD'))}
                                  spids: [6425]
                                )
                              ]
                            )
                          ]
                          spids: [6404 6422]
                        )
                      ]
                      else_action: [
                        (command.If
                          arms: [
                            (if_arm
                              cond: [
                                (command.Sentence
                                  child: 
                                    (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                      {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {(Id.Lit_RBracket ']')}
                                    )
                                  terminator: (Token id:Id.Op_Semi val:';' span_id:6451)
                                )
                              ]
                              action: [
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'Sandstorm requires you to set up a wildcard DNS entry pointing at the server.'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'This allows Sandstorm to allocate new hosts on-the-fly for sandboxing purposes.'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
"Please enter a DNS hostname containing a '*' which maps to your server. For "
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'example, if you have mapped *.foo.example.com to your server, you could enter'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (word_part.EscapedLiteral
                                        token: (Token id:Id.Lit_EscapedChar val:'\\"' span_id:6487)
                                      ) ('*.foo.example.com') 
                                      (word_part.EscapedLiteral
                                        token: (Token id:Id.Lit_EscapedChar val:'\\"' span_id:6489)
                                      ) ('. You can also specify that hosts should have a special')
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ ('prefix, like ') 
                                      (word_part.EscapedLiteral
                                        token: (Token id:Id.Lit_EscapedChar val:'\\"' span_id:6498)
                                      ) ('ss-*.foo.example.com') 
                                      (word_part.EscapedLiteral
                                        token: (Token id:Id.Lit_EscapedChar val:'\\"' span_id:6500)
                                      ) (". Note that if your server's main page")
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'is served over SSL, the wildcard address must support SSL as well, which'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'implies that you must have a wildcard certificate. For local-machine servers,'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'we have mapped *.local.sandstorm.io to 127.0.0.1 for your convenience, so you'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ ('can use ') 
                                      (word_part.EscapedLiteral
                                        token: (Token id:Id.Lit_EscapedChar val:'\\"' span_id:6530)
                                      ) ('*.local.sandstorm.io') 
                                      (word_part.EscapedLiteral
                                        token: (Token id:Id.Lit_EscapedChar val:'\\"' span_id:6532)
                                      ) (' here. If you are serving off a non-standard')
                                    )
                                  }
                                )
                                (C {(echo)} {(DQ ('port, you must include it here as well.'))})
                              ]
                              spids: [6434 6453]
                            )
                          ]
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:WILDCARD_HOST)
                              op: assign_op.Equal
                              rhs: 
                                {
                                  (command_sub
                                    left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:6548)
                                    command_list: 
                                      (command.CommandList
                                        children: [
                                          (C {(prompt)} {(DQ ('Wildcard host:'))} 
                                            {(DQ ($ Id.VSub_DollarName '$DEFAULT_WILDCARD'))}
                                          )
                                        ]
                                      )
                                  )
                                }
                              spids: [6547]
                            )
                          ]
                        )
                        (command.WhileUntil
                          keyword: (Token id:Id.KW_While val:while span_id:6562)
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Pipeline
                                  children: [
                                    (command.DBracket
                                      expr: 
                                        (bool_expr.Binary
                                          op_id: Id.BoolBinary_EqualTilde
                                          left: {(DQ ($ Id.VSub_DollarName '$WILDCARD_HOST'))}
                                          right: 
                                            {(Id.Lit_Other '^') (Id.Lit_Other '[') (Id.Lit_Other '^') 
                                              (Id.Lit_Other '*') (Id.Lit_Other ']') (Id.Lit_Other '*') (Id.Lit_Other '[') (Id.Lit_Other '*') (Id.Lit_Other ']') 
                                              (Id.Lit_Other '[') (Id.Lit_Other '^') (Id.Lit_Other '*') (Id.Lit_Other ']') (Id.Lit_Other '*') (Id.Lit_Other '$')
                                            }
                                        )
                                    )
                                  ]
                                  negated: T
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:6591)
                            )
                          ]
                          body: 
                            (command.DoGroup
                              children: [
                                (C {(error)} 
                                  {
                                    (DQ 
                                      (
'Invalid wildcard host. It must contain exactly one asterisk.'
                                      )
                                    )
                                  }
                                )
                                (command.ShAssignment
                                  pairs: [
                                    (assign_pair
                                      lhs: (sh_lhs_expr.Name name:WILDCARD_HOST)
                                      op: assign_op.Equal
                                      rhs: 
                                        {
                                          (command_sub
                                            left_token: 
                                              (Token
                                                id: Id.Left_DollarParen
                                                val: '$('
                                                span_id: 6604
                                              )
                                            command_list: 
                                              (command.CommandList
                                                children: [
                                                  (C {(prompt)} {(DQ ('Wildcard host:'))} 
                                                    {(DQ ($ Id.VSub_DollarName '$DEFAULT_WILDCARD'))}
                                                  )
                                                ]
                                              )
                                          )
                                        }
                                      spids: [6603]
                                    )
                                  ]
                                )
                              ]
                            )
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_install_dir
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:DIR span_id:6640)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:6647)
                            )
                          ]
                          action: [
                            (C {(local)} 
                              {(Id.Lit_VarLike 'DEFAULT_DIR=') 
                                (DQ ($ Id.VSub_DollarName '$DEFAULT_DIR_FOR_ROOT'))
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                          {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:6677)
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:DEFAULT_DIR)
                                          op: assign_op.Equal
                                          rhs: 
                                            {(DQ ($ Id.VSub_DollarName '$DEFAULT_DIR_FOR_NON_ROOT'))}
                                          spids: [6682]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [6660 6679]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DIR)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 6693
                                          )
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(prompt)} 
                                                {(DQ ('Where would you like to put Sandstorm?'))} {(DQ ($ Id.VSub_DollarName '$DEFAULT_DIR'))}
                                              )
                                            ]
                                          )
                                      )
                                    }
                                  spids: [6692]
                                )
                              ]
                            )
                          ]
                          spids: [6632 6649]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Id.Op_DPipe Id.Op_DPipe]
                                  children: [
                                    (C {(Id.Lit_LBracket '[')} {(-e)} 
                                      {(DQ ($ Id.VSub_DollarName '$DIR') (/sandstorm.conf))} {(Id.Lit_RBracket ']')}
                                    )
                                    (C {(Id.Lit_LBracket '[')} {(-e)} 
                                      {(DQ ($ Id.VSub_DollarName '$DIR') (/var))} {(Id.Lit_RBracket ']')}
                                    )
                                    (C {(Id.Lit_LBracket '[')} {(-e)} 
                                      {(DQ ($ Id.VSub_DollarName '$DIR') (/sandstorm))} {(Id.Lit_RBracket ']')}
                                    )
                                  ]
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:6765)
                            )
                          ]
                          action: [
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {
                                (DQ ('This script is trying to install to ') (${ Id.VSub_Name DIR) (.))
                              }
                            )
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {
                                (DQ ('You seem to already have a ') (${ Id.VSub_Name DIR) 
                                  (
' directory with a Sandstorm installation inside. You should either:'
                                  )
                                )
                              }
                            )
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {
                                (DQ 
                                  (
'1. Reconfigure that Sandstorm install using its configuration file -- '
                                  ) (${ Id.VSub_Name DIR) ('/sandstorm.conf -- or the admin interface. See docs at:')
                                )
                              }
                            )
                            (C {(error)} {(DQ ('https://docs.sandstorm.io/en/latest/administering/'))})
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {
                                (DQ 
                                  (
'2. Uninstall Sandstorm before attempting to perform a new install. Even if you created a sandcats.io hostname, it is safe to uninstall so long as you do not need the data in your Sandstorm install. When you re-install Sandstorm, you can follow a process to use the old hostname with the new install. See uninstall docs at:'
                                  )
                                )
                              }
                            )
                            (C {(error)} 
                              {(DQ ('https://docs.sandstorm.io/en/latest/install/#uninstall'))}
                            )
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {
                                (DQ 
                                  (
'3. Use a different target directory for the new Sandstorm install. Try running install.sh with the -d option.'
                                  )
                                )
                              }
                            )
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {
                                (DQ 
                                  (
'4. Retain your data, but restore your Sandstorm code and configuration to a fresh copy. To do that, keep a backup  of '
                                  ) (${ Id.VSub_Name DIR) 
                                  (
'/var and then do a fresh install; stop the Sandstorm service, and restore your backup of '
                                  ) (${ Id.VSub_Name DIR) ('/var. You may need to adjust permissions after doing that.')
                                )
                              }
                            )
                            (command.Simple
                              words: [
                                {(fail)}
                                {(DQ (E_DIR_ALREADY_EXISTS))}
                                {
                                  (DQ 
                                    (
'Please try one of the above. Contact https://groups.google.com/d/forum/sandstorm-dev for further help.'
                                    )
                                  )
                                }
                              ]
                              more_env: [(env_pair name:REPORT val:{(no)} spids:[6886])]
                            )
                          ]
                          spids: [6726 6767]
                        )
                      ]
                    )
                    (C {(mkdir)} {(-p)} {(DQ ($ Id.VSub_DollarName '$DIR'))})
                    (C {(cd)} {(DQ ($ Id.VSub_DollarName '$DIR'))})
                  ]
                )
            )
            (command.ShFunction
              name: choose_smtp_port
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: 
                                          (Token
                                            id: Id.VSub_Name
                                            val: SMTP_LISTEN_PORT
                                            span_id: 6943
                                          )
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:6950)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:6955)
                            )
                          ]
                          spids: [6933 6952]
                        )
                      ]
                    )
                    (C {(local)} 
                      {(Id.Lit_VarLike 'REQUESTED_SMTP_PORT=') 
                        (command_sub
                          left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:6965)
                          command_list: 
                            (command.CommandList
                              children: [
                                (C {(prompt-numeric)} 
                                  {
                                    (DQ 
                                      (
'Sandstorm grains can receive email. What port should Sandstorm listen on, for inbound SMTP?'
                                      )
                                    )
                                  } {(DQ (${ Id.VSub_Name DEFAULT_SMTP_PORT))}
                                )
                              ]
                            )
                        )
                      }
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-z)} 
                                  {(DQ (${ Id.VSub_Name REQUESTED_SMTP_PORT))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:6994)
                            )
                          ]
                          action: [(C {(choose_smtp_port)})]
                          spids: [6980 6996]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:SMTP_LISTEN_PORT)
                              op: assign_op.Equal
                              rhs: {(DQ (${ Id.VSub_Name REQUESTED_SMTP_PORT))}
                              spids: [7005]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: load_existing_settings
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-e)} {(sandstorm.conf)} 
                                  {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7044)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:7049)
                            )
                          ]
                          spids: [7033 7046]
                        )
                      ]
                    )
                    (C {(echo)} {(DQ ('Found existing sandstorm.conf. Using it.'))})
                    (C {(.)} {(sandstorm.conf)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:SERVER_USER span_id:7074)
                                        suffix_op: 
                                          (suffix_op.Unary
                                            op_id: Id.VTest_ColonPlus
                                            arg_word: {(set)}
                                          )
                                      )
                                    )
                                  } {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(Id.KW_Set set)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7086)
                            )
                          ]
                          action: [
                            (C {(fail)} {(DQ (E_CONF_DOES_NOT_SET_SERVER_USER))} 
                              {
                                (DQ 
                                  (
'Existing config does not set SERVER_USER. Please fix or delete it.'
                                  )
                                )
                              }
                            )
                          ]
                          spids: [7068 7088]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: 
                                          (Token
                                            id: Id.VSub_Name
                                            val: UPDATE_CHANNEL
                                            span_id: 7128
                                          )
                                        suffix_op: 
                                          (suffix_op.Unary
                                            op_id: Id.VTest_ColonHyphen
                                            arg_word: {(none)}
                                          )
                                      )
                                    )
                                  } {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(none)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7140)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEFAULT_UPDATE_CHANNEL)
                                  op: assign_op.Equal
                                  rhs: {($ Id.VSub_DollarName '$UPDATE_CHANNEL')}
                                  spids: [7145]
                                )
                              ]
                            )
                          ]
                          spids: [7122 7142]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_server_user_if_needed
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-e)} {(sandstorm.conf)} 
                                  {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7187)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:7192)
                            )
                          ]
                          spids: [7177 7189]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7223)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SERVER_USER)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 7229
                                          )
                                        command_list: 
                                          (command.CommandList
                                            children: [(C {(id)} {(-un)})]
                                          )
                                      )
                                    }
                                  spids: [7228]
                                )
                              ]
                            )
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:7236)
                            )
                          ]
                          spids: [7207 7225]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: 
                                          (Token
                                            id: Id.VSub_Name
                                            val: DESIRED_SERVER_USER
                                            span_id: 7261
                                          )
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7268)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SERVER_USER)
                                  op: assign_op.Equal
                                  rhs: {(DQ ($ Id.VSub_DollarName '$DESIRED_SERVER_USER'))}
                                  spids: [7273]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:CREATE_SERVER_USER)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [7279]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:ADD_SUDO_USER_TO_SERVER_GROUP)
                                  op: assign_op.Equal
                                  rhs: {(DQ (no))}
                                  spids: [7285]
                                )
                              ]
                            )
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:7291)
                            )
                          ]
                          spids: [7251 7270]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SERVER_USER)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:7303)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt)} {(DQ ('Local user account to run server under:'))} 
                                        {(sandstorm)}
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [7302]
                        )
                      ]
                    )
                    (command.WhileUntil
                      keyword: (Token id:Id.KW_While val:while span_id:7315)
                      cond: [
                        (command.Sentence
                          child: 
                            (C {(Id.Lit_LBracket '[')} {(DQ ($ Id.VSub_DollarName '$SERVER_USER'))} 
                              {(Id.Lit_Equals '=')} {(root)} {(Id.Lit_RBracket ']')}
                            )
                          terminator: (Token id:Id.Op_Semi val:';' span_id:7328)
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(echo)} {(DQ ('Sandstorm cannot run as root!'))})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SERVER_USER)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 7341
                                          )
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(prompt)} 
                                                {(DQ ('Local user account to run server under:'))} {(sandstorm)}
                                              )
                                            ]
                                          )
                                      )
                                    }
                                  spids: [7340]
                                )
                              ]
                            )
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShFunction
              name: create_server_user_if_needed
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Simple
                                  words: [{(id)} {(DQ ($ Id.VSub_DollarName '$SERVER_USER'))}]
                                  redirects: [
                                    (redir.Redir
                                      op: (Token id:Id.Redir_Great val:'>' span_id:7376)
                                      fd: -1
                                      arg_word: {(/dev/null)}
                                    )
                                    (redir.Redir
                                      op: (Token id:Id.Redir_GreatAnd val:'2>&' span_id:7380)
                                      fd: 2
                                      arg_word: {(1)}
                                    )
                                  ]
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7382)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:7387)
                            )
                          ]
                          spids: [7368 7384]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: 
                                          (Token
                                            id: Id.VSub_Name
                                            val: CREATE_SERVER_USER
                                            span_id: 7415
                                          )
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7422)
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} 
                                          {
                                            (DQ ("User account '") 
                                              ($ Id.VSub_DollarName '$SERVER_USER') ("' doesn't exist. Create it?")
                                            )
                                          } {(yes)}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:7439)
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:CREATE_SERVER_USER)
                                          op: assign_op.Equal
                                          rhs: {(yes)}
                                          spids: [7444]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [7427 7441]
                                )
                              ]
                            )
                          ]
                          spids: [7402 7424]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: 
                                          (Token
                                            id: Id.VSub_Name
                                            val: CREATE_SERVER_USER
                                            span_id: 7472
                                          )
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7479)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:7484)
                            )
                          ]
                          spids: [7459 7481]
                        )
                      ]
                    )
                    (C {(useradd)} {(--system)} {(--user-group)} 
                      {(DQ ($ Id.VSub_DollarName '$SERVER_USER'))}
                    )
                    (C {(echo)} 
                      {
                        (DQ ("Note: Sandstorm's storage will only be accessible to the group '") 
                          ($ Id.VSub_DollarName '$SERVER_USER') ("'.")
                        )
                      }
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (no))} {(Id.Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: 
                                          (Token
                                            id: Id.VSub_Name
                                            val: ADD_SUDO_USER_TO_SERVER_GROUP
                                            span_id: 7574
                                          )
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7581)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:7586)
                            )
                          ]
                          spids: [7562 7583]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-n)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:SUDO_USER span_id:7601)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7607)
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} 
                                          {
                                            (DQ ("Add user '") ($ Id.VSub_DollarName '$SUDO_USER') 
                                              ("' to group '") ($ Id.VSub_DollarName '$SERVER_USER') ("'?")
                                            )
                                          } {(no)}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:7626)
                                    )
                                  ]
                                  action: [
                                    (C {(usermod)} {(-a)} {(-G)} 
                                      {(DQ ($ Id.VSub_DollarName '$SERVER_USER'))} {(DQ ($ Id.VSub_DollarName '$SUDO_USER'))}
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
"Added. Don't forget that group changes only apply at next login."
                                          )
                                        )
                                      }
                                    )
                                  ]
                                  spids: [7612 7628]
                                )
                              ]
                            )
                          ]
                          spids: [7593 7609]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_port
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:PORT span_id:7682)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7689)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:7694)
                            )
                          ]
                          spids: [7672 7691]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:PORT)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:7702)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt-numeric)} {(DQ ('Server main HTTP port:'))} 
                                        {($ Id.VSub_DollarName '$DEFAULT_PORT')}
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [7701]
                        )
                      ]
                    )
                    (command.WhileUntil
                      keyword: (Token id:Id.KW_While val:while span_id:7714)
                      cond: [
                        (command.Sentence
                          child: 
                            (C {(Id.Lit_LBracket '[')} {(DQ ($ Id.VSub_DollarName '$PORT'))} {(-lt)} 
                              {(1024)} {(Id.Lit_RBracket ']')}
                            )
                          terminator: (Token id:Id.Op_Semi val:';' span_id:7727)
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'Ports below 1024 require root privileges. Sandstorm does not run as root.'
                                  )
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ ('To use port ') ($ Id.VSub_DollarName '$PORT') 
                                  (", you'll need to set up a reverse proxy like nginx that ")
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'forwards to the internal higher-numbered port. The Sandstorm git repo '
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('contains an example nginx config for this.'))})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:PORT)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 7763
                                          )
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(prompt-numeric)} {(DQ ('Server main HTTP port:'))} 
                                                {($ Id.VSub_DollarName '$DEFAULT_PORT')}
                                              )
                                            ]
                                          )
                                      )
                                    }
                                  spids: [7762]
                                )
                              ]
                            )
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_mongo_port
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:MONGO_PORT span_id:7800)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7807)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:7812)
                            )
                          ]
                          spids: [7790 7809]
                        )
                      ]
                    )
                    (C {(local)} 
                      {(Id.Lit_VarLike 'DEFAULT_MONGO_PORT=') 
                        (DQ 
                          (word_part.ArithSub
                            anode: 
                              (arith_expr.Binary
                                op_id: Id.Arith_Plus
                                left: 
                                  (arith_expr.VarRef
                                    token: (Token id:Id.Lit_ArithVarLike val:PORT span_id:7832)
                                  )
                                right: (arith_expr.ArithWord w:{(Id.Lit_Digits 1)})
                              )
                          )
                        )
                      }
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ ($ Id.VSub_DollarName '$PORT'))} {(-lt)} 
                                  {(1024)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7856)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEFAULT_MONGO_PORT)
                                  op: assign_op.Equal
                                  rhs: {(DQ (6081))}
                                  spids: [7861]
                                )
                              ]
                            )
                          ]
                          spids: [7842 7858]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:MONGO_PORT)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:7872)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt-numeric)} 
                                        {(DQ ('Database port (choose any unused port):'))} {(DQ (${ Id.VSub_Name DEFAULT_MONGO_PORT))}
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [7871]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_external_or_internal
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$USE_EXTERNAL_INTERFACE'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7916)
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} {(DQ ('Expose to localhost only?'))} {(yes)})
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:7931)
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                          op: assign_op.Equal
                                          rhs: {(DQ (no))}
                                          spids: [7936]
                                        )
                                      ]
                                    )
                                  ]
                                  spids: [7921 7933]
                                )
                              ]
                              else_action: [
                                (command.ShAssignment
                                  pairs: [
                                    (assign_pair
                                      lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                      op: assign_op.Equal
                                      rhs: {(DQ (yes))}
                                      spids: [7945]
                                    )
                                  ]
                                )
                              ]
                            )
                          ]
                          spids: [7900 7918]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: configure_auto_updates
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-n)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: 
                                          (Token
                                            id: Id.VSub_Name
                                            val: UPDATE_CHANNEL
                                            span_id: 7978
                                          )
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:7984)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:7989)
                            )
                          ]
                          spids: [7970 7986]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(prompt-yesno)} {(DQ ('Automatically keep Sandstorm updated?'))} 
                                  {(yes)}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:8009)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL)
                                  op: assign_op.Equal
                                  rhs: {($ Id.VSub_DollarName '$DEFAULT_UPDATE_CHANNEL')}
                                  spids: [8014]
                                )
                              ]
                            )
                          ]
                          spids: [8000 8011]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL)
                              op: assign_op.Equal
                              rhs: {(none)}
                              spids: [8021]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: configure_dev_accounts
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ (${ Id.VSub_Name ALLOW_DEV_ACCOUNTS))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:8058)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:8063)
                            )
                          ]
                          spids: [8041 8060]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ (${ Id.VSub_Name USE_EXTERNAL_INTERFACE))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:8096)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:8101)
                            )
                          ]
                          spids: [8078 8098]
                        )
                      ]
                    )
                    (C {(echo)} 
                      {(DQ ("Sandstorm supports 'dev accounts', a feature that lets anyone log in"))}
                    )
                    (C {(echo)} 
                      {(DQ ('as admin and other sample users to a Sandstorm server. We recommend'))}
                    )
                    (C {(echo)} 
                      {(DQ ('it for app development, and absolutely do not recommend it for'))}
                    )
                    (C {(echo)} {(DQ ('a server on the public Internet.'))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: (C {(prompt-yesno)} {(DQ ('Enable dev accounts?'))} {(DQ (yes))})
                              terminator: (Token id:Id.Op_Semi val:';' span_id:8149)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:ALLOW_DEV_ACCOUNTS)
                                  op: assign_op.Equal
                                  rhs: {(yes)}
                                  spids: [8154]
                                )
                              ]
                            )
                          ]
                          spids: [8137 8151]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: save_config
              body: 
                (command.BraceGroup
                  children: [
                    (command.Simple
                      words: [
                        {(writeConfig)}
                        {(SERVER_USER)}
                        {(PORT)}
                        {(MONGO_PORT)}
                        {(BIND_IP)}
                        {(BASE_URL)}
                        {(WILDCARD_HOST)}
                        {(UPDATE_CHANNEL)}
                        {(ALLOW_DEV_ACCOUNTS)}
                        {(SMTP_LISTEN_PORT)}
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_Great val:'>' span_id:8190)
                          fd: -1
                          arg_word: {(sandstorm.conf)}
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:8211)
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [{(writeConfig)} {(SANDCATS_BASE_DOMAIN)}]
                              redirects: [
                                (redir.Redir
                                  op: (Token id:Id.Redir_DGreat val:'>>' span_id:8220)
                                  fd: -1
                                  arg_word: {(sandstorm.conf)}
                                )
                              ]
                            )
                          ]
                          spids: [8195 8213]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$SANDCATS_HTTPS_SUCCESSFUL'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:8244)
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [{(writeConfig)} {(HTTPS_PORT)}]
                              redirects: [
                                (redir.Redir
                                  op: (Token id:Id.Redir_DGreat val:'>>' span_id:8253)
                                  fd: -1
                                  arg_word: {(sandstorm.conf)}
                                )
                              ]
                            )
                          ]
                          spids: [8228 8246]
                        )
                      ]
                    )
                    (C {(echo)})
                    (C {(echo)} 
                      {(DQ ('Config written to ') ($ Id.VSub_DollarName '$PWD') (/sandstorm.conf.))}
                    )
                  ]
                )
            )
            (command.ShFunction
              name: download_latest_bundle_and_extract_if_needed
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-n)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:BUNDLE_FILE span_id:8299)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:8305)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:8310)
                            )
                          ]
                          spids: [8291 8307]
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (DQ ('Finding latest build for ') 
                          ($ Id.VSub_DollarName '$DEFAULT_UPDATE_CHANNEL') (' channel...')
                        )
                      }
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:BUILD)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (DQ 
                                (command_sub
                                  left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:8344)
                                  command_list: 
                                    (command.CommandList
                                      children: [
                                        (C {(curl)} {(-A)} 
                                          {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {(-fs)} 
                                          {
                                            (DQ ('https://install.sandstorm.io/') 
                                              ($ Id.VSub_DollarName '$DEFAULT_UPDATE_CHANNEL') ('?from=0&type=install_v2')
                                            )
                                          }
                                        )
                                      ]
                                    )
                                )
                              )
                            }
                          spids: [8342]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:BUILD_DIR)
                          op: assign_op.Equal
                          rhs: {(DQ (sandstorm-) (${ Id.VSub_Name BUILD))}
                          spids: [8364]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.DBracket
                                  expr: 
                                    (bool_expr.LogicalNot
                                      child: 
                                        (bool_expr.Binary
                                          op_id: Id.BoolBinary_EqualTilde
                                          left: {(DQ ($ Id.VSub_DollarName '$BUILD'))}
                                          right: 
                                            {(Id.Lit_Other '^') (Id.Lit_Other '[') (0-9) 
                                              (Id.Lit_Other ']') (Id.Lit_Other '+') (Id.Lit_Other '$')
                                            }
                                        )
                                    )
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:8394)
                            )
                          ]
                          action: [
                            (C {(fail)} {(DQ (E_INVALID_BUILD_NUM))} 
                              {
                                (DQ ('Server returned invalid build number: ') 
                                  ($ Id.VSub_DollarName '$BUILD')
                                )
                              }
                            )
                          ]
                          spids: [8374 8396]
                        )
                      ]
                    )
                    (command.ShFunction
                      name: do-download
                      body: 
                        (command.BraceGroup
                          children: [
                            (C {(rm)} {(-rf)} {(DQ (${ Id.VSub_Name BUILD_DIR))})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:WORK_DIR)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (command_sub
                                          left_token: 
                                            (Token
                                              id: Id.Left_DollarParen
                                              val: '$('
                                              span_id: 8435
                                            )
                                          command_list: 
                                            (command.CommandList
                                              children: [
                                                (C {(mktemp)} {(-d)} 
                                                  {(./sandstorm-installer.XXXXXXXXXX)}
                                                )
                                              ]
                                            )
                                        )
                                      )
                                    }
                                  spids: [8433]
                                )
                              ]
                            )
                            (C {(local)} 
                              {(Id.Lit_VarLike 'URL=') 
                                (DQ ('https://dl.sandstorm.io/sandstorm-') 
                                  ($ Id.VSub_DollarName '$BUILD') (.tar.xz)
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('Downloading: ') ($ Id.VSub_DollarName '$URL'))})
                            (C {(retryable_curl)} {(DQ ($ Id.VSub_DollarName '$URL'))} 
                              {
                                (DQ ($ Id.VSub_DollarName '$WORK_DIR') (/sandstorm-) 
                                  ($ Id.VSub_DollarName '$BUILD') (.tar.xz)
                                )
                              }
                            )
                            (C {(retryable_curl)} {(DQ ($ Id.VSub_DollarName '$URL') (.sig))} 
                              {
                                (DQ ($ Id.VSub_DollarName '$WORK_DIR') (/sandstorm-) 
                                  ($ Id.VSub_DollarName '$BUILD') (.tar.xz.sig)
                                )
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.Simple
                                          words: [{(which)} {(gpg)}]
                                          redirects: [
                                            (redir.Redir
                                              op: (Token id:Id.Redir_Great val:'>' span_id:8499)
                                              fd: -1
                                              arg_word: {(/dev/null)}
                                            )
                                          ]
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:8502)
                                    )
                                  ]
                                  action: [
                                    (C {(export)} 
                                      {(Id.Lit_VarLike 'GNUPGHOME=') 
                                        (DQ ($ Id.VSub_DollarName '$WORK_DIR') (/.gnupg))
                                      }
                                    )
                                    (C {(mkdir)} {(-m)} {(0700)} {(-p)} 
                                      {(DQ ($ Id.VSub_DollarName '$GNUPGHOME'))}
                                    )
                                    (command.Simple
                                      words: [{(gpg)} {(--dearmor)}]
                                      redirects: [
                                        (redir.Redir
                                          op: (Token id:Id.Redir_Great val:'>' span_id:8538)
                                          fd: -1
                                          arg_word: 
                                            {
                                              (DQ ($ Id.VSub_DollarName '$WORK_DIR') 
                                                (/sandstorm-keyring.gpg)
                                              )
                                            }
                                        )
                                        (redir.HereDoc
                                          op: (Token id:Id.Redir_DLess val:'<<' span_id:8545)
                                          fd: -1
                                          here_begin: {(__EOF__)}
                                          here_end_span_id: 8580
                                          stdin_parts: [
                                            ('-----BEGIN PGP PUBLIC KEY BLOCK-----\n')
                                            ('Version: GnuPG v1\n')
                                            ('\n')
                                            (
'mQENBFX8ypkBCAC8sjX5yZqKdW8nY7aE/GpVeS+qSCbpYSJwixYNFXbz3MQihR3S\n'
                                            )
                                            (
'suvg5uw1KyuQb23c0LwirfxazVf7txKhQNaNU3ek62LG3wcGeBrvQGsIUMbkatay\n'
                                            )
                                            (
'/163CLeVWfSK1Z4pFc4dhdjXYSOz0oZxd7Mp78crBbGKmyn7PtzdAqt+XfEXNuee\n'
                                            )
                                            (
'cDbx++P57n5s5xc5fQWznt333IMgmgTREGUROfh4kL376rFAS208XIywJlUVkoKM\n'
                                            )
                                            (
'kIzgcjevFGwYKdsLigHXCDp9toQHl8oPjFV+RE8Br8ciJlMp9CqCfHGwj0Orxasc\n'
                                            )
                                            (
'e9moLqqUc+iKdg9bQfuAbJ/jFNhGmV/CVv9tABEBAAG0LlNhbmRzdG9ybS5pbyAo\n'
                                            )
                                            (
'cmVsZWFzZXMpIDxzdXBwb3J0QHNhbmRzdG9ybS5pbz6JATgEEwECACIFAlX8ypkC\n'
                                            )
                                            (
'GwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEGPyJ0mdqMy91bYH/iTg9qbw\n'
                                            )
                                            (
'G3th57Yf70NtyMJE3UBFDYDNAgT45UBEHoHhQM5cdFu/EIHggOKl/A2zL19Nh555\n'
                                            )
                                            (
'5F5o3jiJChQ0cvpoVnDdA5lRKD9iK6hzAba9fCVAx/od1PULQP7KV+uHTQuclSFO\n'
                                            )
                                            (
'DBvpgT8bMY9LmlpTl+l2lvYd+c50w3jZMFwh8JrJYAc3X0kBfVEywVZkjH8Nw5nD\n'
                                            )
                                            (
'v/j5Of3XXfEg84tNyWSYUMrYVORJyfHtA9e3JXNv5BMxH73AVLnyCJhCaodQsC6Z\n'
                                            )
                                            (
'hFkHUvvRb58ZqKXMtLYTd/8XLIvpkgRNX6EHWDslJh3BaBwHSuqDNssh1TW5xPjA\n'
                                            )
                                            (
'9vkPDzeZfLkuxpy5AQ0EVfzKmQEIANyi22M/3KhkghsPA6Rpha1lx6JJCb4p7E21\n'
                                            )
                                            (
'y82OGFUwcMpZkSgh1lARgp/Mvc2CHhAXi6NkGbgYc1q5rgARSvim2EMZNQOEqRb9\n'
                                            )
                                            (
'teEeI3w7Nz8Q/WoWck9WaXg8EdELtBOXYgVEirVddUl6ftUvCeBh3hE2Y/CLQSXL\n'
                                            )
                                            (
'CYXdQ2/MN6xV8tepuWOu0aPxxPUNea9ceDNZ8/CXEL32pzv9SUX/3KgSnFTzmxNP\n'
                                            )
                                            (
'thzXGuaAQGMZRu3cdTSeK9UUX4L3lxv7p0nE/2K18MU3FayTJqspfUCc4BgHZRMN\n'
                                            )
                                            (
'sh+2/YNfJgi0uWex1WnU94ZIp4A0uic54bU1ZECSwxg81KHaEEkAEQEAAYkBHwQY\n'
                                            )
                                            (
'AQIACQUCVfzKmQIbDAAKCRBj8idJnajMvZgPB/0THpTPnfsYNkwQrBsrTq413ZTF\n'
                                            )
                                            (
'JmVyeZ9xnGDImOdyHhGLlnLC1YEnaNUVEyMKifya4TF2utrLrsMT9TC/dWvFsYlJ\n'
                                            )
                                            (
'oMcUpaSlrFoAoPp3pdOGCIRYNhWGHoxy0Ti1WAa/6A+GoHJpUEz85/jD4vjgYlCX\n'
                                            )
                                            (
'ZFW1Pji9PbdIZFZQR4FyYBkkZOUq6yyTNR0syQPVy3EsPVvXzszm2zV/1YjGymgj\n'
                                            )
                                            (
'MKeYR9+VU+PlFAY9wwLWLTFeSzxTyVjbPwF5bWHV32GM8g0/NgA6a1JLL40v7pqf\n'
                                            )
                                            (
'uYvFk2KJpo3gZNGJ72gLkSzie7Eu1/V67JIG9TwfrJUEj8Uwd5zPv1MOqfWl\n'
                                            )
                                            ('=OiS5\n')
                                            ('-----END PGP PUBLIC KEY BLOCK-----\n')
                                          ]
                                        )
                                      ]
                                    )
                                    (command.If
                                      arms: [
                                        (if_arm
                                          cond: [
                                            (command.Sentence
                                              child: 
                                                (command.Pipeline
                                                  children: [
                                                    (command.Simple
                                                      words: [
                                                        {(gpg)}
                                                        {(--no-default-keyring)}
                                                        {(--keyring)}
                                                        {($ Id.VSub_DollarName '$WORK_DIR') 
                                                          (/sandstorm-keyring.gpg)
                                                        }
                                                        {(--status-fd)}
                                                        {(1)}
                                                        {(--verify)}
                                                        (word.BracedTree
                                                          parts: [
                                                            ($ Id.VSub_DollarName '$WORK_DIR')
                                                            (/sandstorm-)
                                                            ($ Id.VSub_DollarName '$BUILD')
                                                            (.tar.xz)
                                                            (word_part.BracedTuple
                                                              words: [{(.sig)} {}]
                                                            )
                                                          ]
                                                        )
                                                      ]
                                                      redirects: [
                                                        (redir.Redir
                                                          op: 
                                                            (Token
                                                              id: Id.Redir_Great
                                                              val: '2>'
                                                              span_id: 8611
                                                            )
                                                          fd: 2
                                                          arg_word: {(/dev/null)}
                                                        )
                                                      ]
                                                    )
                                                    (C {(grep)} {(-q)} 
                                                      {
                                                        (SQ 
                                                          (Token
                                                            id: Id.Lit_Chars
                                                            val: 
'^\\[GNUPG:\\] VALIDSIG 160D2D577518B58D94C9800B63F227499DA8CCBD '
                                                            span_id: 8623
                                                          )
                                                        )
                                                      }
                                                    )
                                                  ]
                                                  negated: F
                                                )
                                              terminator: (Token id:Id.Op_Semi val:';' span_id:8625)
                                            )
                                          ]
                                          action: [(C {(echo)} {(DQ ('GPG signature is valid.'))})]
                                          spids: [8583 8627]
                                        )
                                      ]
                                      else_action: [
                                        (C {(rm)} {(-rf)} {(sandstorm-) ($ Id.VSub_DollarName '$BUILD')})
                                        (C {(fail)} {(DQ (E_INVALID_GPG_SIG))} 
                                          {
                                            (DQ 
                                              (
'GPG signature is NOT valid! Please report to security@sandstorm.io immediately!'
                                              )
                                            )
                                          }
                                        )
                                      ]
                                    )
                                    (C {(unset)} {(GNUPGHOME)})
                                  ]
                                  spids: [8493 8504]
                                )
                              ]
                              else_action: [
                                (command.Simple
                                  words: [
                                    {(echo)}
                                    {
                                      (DQ 
                                        (
"WARNING: gpg not installed; not verifying signatures (but it's HTTPS so you're probably fine)"
                                        )
                                      )
                                    }
                                  ]
                                  redirects: [
                                    (redir.Redir
                                      op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:8677)
                                      fd: -1
                                      arg_word: {(2)}
                                    )
                                  ]
                                )
                              ]
                            )
                            (C {(tar)} {(Jxof)} 
                              {
                                (DQ ($ Id.VSub_DollarName '$WORK_DIR') (/sandstorm-) 
                                  ($ Id.VSub_DollarName '$BUILD') (.tar.xz)
                                )
                              }
                            )
                            (C {(rm)} {(-rf)} {(DQ ($ Id.VSub_DollarName '$WORK_DIR'))})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-e)} 
                                          {(DQ ($ Id.VSub_DollarName '$BUILD_DIR'))} {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:8720)
                                    )
                                  ]
                                  action: [
                                    (C {(fail)} {(DQ (E_BAD_PACKAGE))} 
                                      {
                                        (DQ ('Bad package -- did not contain ') 
                                          ($ Id.VSub_DollarName '$BUILD_DIR') (' directory.')
                                        )
                                      }
                                    )
                                  ]
                                  spids: [8707 8722]
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.AndOr
                                          ops: [Id.Op_DPipe]
                                          children: [
                                            (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-e)} 
                                              {(DQ ($ Id.VSub_DollarName '$BUILD_DIR') (/buildstamp))} {(Id.Lit_RBracket ']')}
                                            )
                                            (C {(Id.Lit_LBracket '[')} 
                                              {
                                                (command_sub
                                                  left_token: 
                                                    (Token
                                                      id: Id.Left_DollarParen
                                                      val: '$('
                                                      span_id: 8763
                                                    )
                                                  command_list: 
                                                    (command.CommandList
                                                      children: [
                                                        (C {(stat)} {(-c)} {(Id.Lit_Other '%') (Y)} 
                                                          {
                                                            (DQ ($ Id.VSub_DollarName '$BUILD_DIR') 
                                                              (/buildstamp)
                                                            )
                                                          }
                                                        )
                                                      ]
                                                    )
                                                )
                                              } {(-lt)} 
                                              {
                                                (word_part.ArithSub
                                                  anode: 
                                                    (arith_expr.Binary
                                                      op_id: Id.Arith_Minus
                                                      left: 
                                                        (arith_expr.ArithWord
                                                          w: 
                                                            {
                                                              (command_sub
                                                                left_token: 
                                                                  (Token
                                                                    id: Id.Left_DollarParen
                                                                    val: '$('
                                                                    span_id: 8781
                                                                  )
                                                                command_list: 
                                                                  (command.CommandList
                                                                    children: [
                                                                      (C {(date)} 
                                                                        {(Id.Lit_Other '+') 
                                                                          (Id.Lit_Other '%') (s)
                                                                        }
                                                                      )
                                                                    ]
                                                                  )
                                                              )
                                                            }
                                                        )
                                                      right: 
                                                        (arith_expr.Binary
                                                          op_id: Id.Arith_Star
                                                          left: 
                                                            (arith_expr.Binary
                                                              op_id: Id.Arith_Star
                                                              left: 
                                                                (arith_expr.Binary
                                                                  op_id: Id.Arith_Star
                                                                  left: 
                                                                    (arith_expr.ArithWord
                                                                      w: {(Id.Lit_Digits 30)}
                                                                    )
                                                                  right: 
                                                                    (arith_expr.ArithWord
                                                                      w: {(Id.Lit_Digits 24)}
                                                                    )
                                                                )
                                                              right: 
                                                                (arith_expr.ArithWord
                                                                  w: {(Id.Lit_Digits 60)}
                                                                )
                                                            )
                                                          right: 
                                                            (arith_expr.ArithWord
                                                              w: {(Id.Lit_Digits 60)}
                                                            )
                                                        )
                                                    )
                                                )
                                              } {(Id.Lit_RBracket ']')}
                                            )
                                          ]
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:8803)
                                    )
                                  ]
                                  action: [
                                    (C {(rm)} {(-rf)} {(DQ ($ Id.VSub_DollarName '$BUILD_DIR'))})
                                    (C {(fail)} {(DQ (E_PKG_STALE))} 
                                      {
                                        (DQ 
                                          (
'The downloaded package seems to be more than a month old. Please verify that your'
                                          )
                                        )
                                      } {(DQ ("computer's clock is correct and try again. It could also be that an attacker is"))} 
                                      {
                                        (DQ 
                                          (
'trying to trick you into installing an old version. Please contact'
                                          )
                                        )
                                      } {(DQ ('security@sandstorm.io if the problem persists.'))}
                                    )
                                  ]
                                  spids: [8742 8805]
                                )
                              ]
                            )
                          ]
                        )
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-e)} {($ Id.VSub_DollarName '$BUILD_DIR')} 
                                  {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:8862)
                            )
                          ]
                          action: [
                            (C {(echo)} 
                              {
                                (DQ ($ Id.VSub_DollarName '$BUILD_DIR') 
                                  (' is already present. Should I use it or re-download?')
                                )
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.Pipeline
                                          children: [
                                            (C {(prompt-yesno)} {(DQ ('Use existing copy?'))} {(yes)})
                                          ]
                                          negated: T
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:8886)
                                    )
                                  ]
                                  action: [(C {(do-download)})]
                                  spids: [8875 8888]
                                )
                              ]
                            )
                          ]
                          spids: [8853 8864]
                        )
                      ]
                      else_action: [(C {(do-download)})]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: extract_bundle_if_provided
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:BUNDLE_FILE span_id:8931)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:8937)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:8942)
                            )
                          ]
                          spids: [8923 8939]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {($ Id.VSub_DollarName '$BUILD')} 
                                  {(Id.Lit_Equals '=')} {(0)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:8965)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BUILD_DIR)
                                  op: assign_op.Equal
                                  rhs: 
                                    {(sandstorm-custom.) 
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 8972
                                          )
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(date)} 
                                                {(Id.Lit_Other '+') 
                                                  (SQ 
                                                    (Token
                                                      id: Id.Lit_Chars
                                                      val: '%Y-%m-%d_%H-%M-%S'
                                                      span_id: 8977
                                                    )
                                                  )
                                                }
                                              )
                                            ]
                                          )
                                      )
                                    }
                                  spids: [8970]
                                )
                              ]
                            )
                          ]
                          spids: [8954 8967]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:BUILD_DIR)
                              op: assign_op.Equal
                              rhs: {(sandstorm-) ($ Id.VSub_DollarName '$BUILD')}
                              spids: [8985]
                            )
                          ]
                        )
                      ]
                    )
                    (C {(rm)} {(-rf)} {(DQ ($ Id.VSub_DollarName '$BUILD_DIR'))})
                    (C {(mkdir)} {(DQ ($ Id.VSub_DollarName '$BUILD_DIR'))})
                    (command.Subshell
                      command_list: 
                        (command.CommandList
                          children: [
                            (command.AndOr
                              ops: [Id.Op_DAmp]
                              children: [
                                (C {(cd)} {(DQ ($ Id.VSub_DollarName '$BUILD_DIR'))})
                                (C {(tar)} {(Jxof)} {(DQ ($ Id.VSub_DollarName '$BUNDLE_FILE'))} 
                                  {(--strip) (Id.Lit_Equals '=') (1)}
                                )
                              ]
                            )
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShFunction
              name: make_runtime_directories
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:GROUP)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:9043)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(id)} {(-g)} {($ Id.VSub_DollarName '$SERVER_USER')})
                                    ]
                                  )
                              )
                            }
                          spids: [9042]
                        )
                      ]
                    )
                    (C {(mkdir)} {(-p)} 
                      (word.BracedTree
                        parts: [(var/) (word_part.BracedTuple words:[{(log)} {(pid)} {(mongo)}])]
                      ) 
                      (word.BracedTree
                        parts: [
                          (var/sandstorm/)
                          (word_part.BracedTuple
                            words: [{(apps)} {(grains)} {(downloads)}]
                          )
                        ]
                      )
                    )
                    (C {(ln)} {(-sfT)} {($ Id.VSub_DollarName '$BUILD_DIR')} {(latest)})
                    (C {(ln)} {(-sfT)} {(latest/sandstorm)} {(sandstorm)})
                  ]
                )
            )
            (command.ShFunction
              name: set_permissions
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9136)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:9141)
                            )
                          ]
                          spids: [9120 9138]
                        )
                      ]
                    )
                    (C {(local)} {(Id.Lit_VarLike 'ADMIN_TOKEN_PATH=')})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-e)} 
                                  {(DQ (${ Id.VSub_Name ADMIN_TOKEN_PATH))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9167)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:ADMIN_TOKEN_PATH)
                                  op: assign_op.Equal
                                  rhs: {(DQ (var/sandstorm/adminToken))}
                                  spids: [9172]
                                )
                              ]
                            )
                          ]
                          spids: [9153 9169]
                        )
                      ]
                    )
                    (C {(chown)} {(-R)} 
                      {($ Id.VSub_DollarName '$SERVER_USER') (Id.Lit_Other ':') 
                        ($ Id.VSub_DollarName '$GROUP')
                      } (word.BracedTree parts:[(var/) (word_part.BracedTuple words:[{(log)} {(pid)} {(mongo)}])]) 
                      (word.BracedTree
                        parts: [
                          (var/sandstorm/)
                          (word_part.BracedTuple
                            words: [{(apps)} {(grains)} {(downloads)}]
                          )
                        ]
                      ) {($ Id.VSub_DollarName '$ADMIN_TOKEN_PATH')}
                    )
                    (C {(chown)} {(root) (Id.Lit_Other ':') ($ Id.VSub_DollarName '$GROUP')} 
                      (word.BracedTree
                        parts: [
                          (var/)
                          (word_part.BracedTuple
                            words: [{(log)} {(pid)} {(mongo)} {(sandstorm)}]
                          )
                        ]
                      ) 
                      (word.BracedTree
                        parts: [
                          (var/sandstorm/)
                          (word_part.BracedTuple
                            words: [{(apps)} {(grains)} {(downloads)}]
                          )
                        ]
                      ) {($ Id.VSub_DollarName '$ADMIN_TOKEN_PATH')}
                    )
                    (C {(chmod)} {(-R)} 
                      {(Id.Lit_VarLike 'g=') (rwX) (Id.Lit_Comma ',') (Id.Lit_VarLike 'o=')} 
                      (word.BracedTree
                        parts: [
                          (var/)
                          (word_part.BracedTuple
                            words: [{(log)} {(pid)} {(mongo)} {(sandstorm)}]
                          )
                        ]
                      ) 
                      (word.BracedTree
                        parts: [
                          (var/sandstorm/)
                          (word_part.BracedTuple
                            words: [{(apps)} {(grains)} {(downloads)}]
                          )
                        ]
                      ) {($ Id.VSub_DollarName '$ADMIN_TOKEN_PATH')}
                    )
                  ]
                )
            )
            (command.ShFunction
              name: install_sandstorm_symlinks
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9313)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:9318)
                            )
                          ]
                          spids: [9297 9315]
                        )
                      ]
                    )
                    (C {(local)} {(Id.Lit_VarLike 'FAILED_TO_WRITE_SYMLINK=') (DQ (no))})
                    (command.AndOr
                      ops: [Id.Op_DPipe]
                      children: [
                        (C {(ln)} {(-sfT)} {($ Id.VSub_DollarName '$PWD') (/sandstorm)} 
                          {(/usr/local/bin/sandstorm)}
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:FAILED_TO_WRITE_SYMLINK)
                              op: assign_op.Equal
                              rhs: {(yes)}
                              spids: [9349]
                            )
                          ]
                        )
                      ]
                    )
                    (command.AndOr
                      ops: [Id.Op_DPipe]
                      children: [
                        (C {(ln)} {(-sfT)} {($ Id.VSub_DollarName '$PWD') (/sandstorm)} 
                          {(/usr/local/bin/spk)}
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:FAILED_TO_WRITE_SYMLINK)
                              op: assign_op.Equal
                              rhs: {(yes)}
                              spids: [9364]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {(DQ (${ Id.VSub_Name FAILED_TO_WRITE_SYMLINK))} {(Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9399)
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'*** WARNING: /usr/local/bin was not writeable. To run sandstorm or spk manually, use:'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ (' - ') ($ Id.VSub_DollarName '$PWD') (/sandstorm))})
                            (C {(echo)} {(DQ (' - ') ($ Id.VSub_DollarName '$PWD') ('/sandstorm spk'))})
                            (C {(echo)} {(DQ )})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:9441)
                            )
                          ]
                          spids: [9381 9401]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: ask_about_starting_at_boot
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9478)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:START_AT_BOOT)
                                  op: assign_op.Equal
                                  rhs: {(DQ (no))}
                                  spids: [9483]
                                )
                              ]
                            )
                          ]
                          spids: [9461 9480]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:START_AT_BOOT span_id:9507)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9514)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:9519)
                            )
                          ]
                          spids: [9497 9516]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(prompt-yesno)} 
                                  {
                                    (DQ ('Start sandstorm at system boot (using ') 
                                      ($ Id.VSub_DollarName '$INIT_SYSTEM') (')?')
                                    )
                                  } {(yes)}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9537)
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:START_AT_BOOT)
                                  op: assign_op.Equal
                                  rhs: {(yes)}
                                  spids: [9542]
                                )
                              ]
                            )
                          ]
                          spids: [9526 9539]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: configure_start_at_boot_if_desired
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SANDSTORM_NEEDS_TO_BE_STARTED)
                          op: assign_op.Equal
                          rhs: {(DQ (yes))}
                          spids: [9558]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:START_AT_BOOT span_id:9586)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9593)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:9598)
                            )
                          ]
                          spids: [9573 9595]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (systemd))} {(Id.Lit_Equals '=')} 
                                  {(DQ (${ Id.VSub_Name INIT_SYSTEM))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9623)
                            )
                          ]
                          action: [
                            (C {(configure_systemd_init_system)})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDSTORM_NEEDS_TO_BE_STARTED)
                                  op: assign_op.Equal
                                  rhs: {(no)}
                                  spids: [9631]
                                )
                              ]
                            )
                          ]
                          spids: [9605 9625]
                        )
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (sysvinit))} {(Id.Lit_Equals '=')} 
                                  {(DQ (${ Id.VSub_Name INIT_SYSTEM))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9653)
                            )
                          ]
                          action: [
                            (C {(configure_sysvinit_init_system)})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDSTORM_NEEDS_TO_BE_STARTED)
                                  op: assign_op.Equal
                                  rhs: {(no)}
                                  spids: [9661]
                                )
                              ]
                            )
                          ]
                          spids: [9635 9655]
                        )
                      ]
                      else_action: [
                        (C {(echo)} 
                          {
                            (DQ 
                              (
"Note: I don't know how to set up sandstorm to auto-run at startup on"
                              )
                            )
                          }
                        )
                        (C {(echo)} {(DQ ('  your system. :('))})
                        (C {(echo)})
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: configure_systemd_init_system
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Id.Lit_VarLike 'SYSTEMD_UNIT=') (DQ (sandstorm.service))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Pipeline
                                  children: [
                                    (C {(systemctl)} {(list-unit-files)})
                                    (C {(grep)} {(-q)} {($ Id.VSub_DollarName '$SYSTEMD_UNIT')})
                                  ]
                                  negated: F
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9736)
                            )
                          ]
                          action: [
                            (command.AndOr
                              ops: [Id.Op_DPipe]
                              children: [(C {(systemctl)} {(stop)} {(sandstorm)}) (C {(true)})]
                            )
                          ]
                          spids: [9723 9738]
                        )
                      ]
                    )
                    (command.ForEach
                      iter_name: SYSTEMD_UNIT_PATH
                      iter_words: [
                        {(/etc/systemd/system)}
                        {(/run/systemd/system)}
                        {(/usr/lib/systemd/system)}
                      ]
                      do_arg_iter: F
                      body: 
                        (command.DoGroup
                          children: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} {(-e)} 
                                          {($ Id.VSub_DollarName '$SYSTEMD_UNIT_PATH') (/) 
                                            ($ Id.VSub_DollarName '$SYSTEMD_UNIT')
                                          } {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:9788)
                                    )
                                  ]
                                  action: [
                                    (C {(rm)} 
                                      {($ Id.VSub_DollarName '$SYSTEMD_UNIT_PATH') (/) 
                                        ($ Id.VSub_DollarName '$SYSTEMD_UNIT')
                                      }
                                    )
                                  ]
                                  spids: [9776 9790]
                                )
                              ]
                            )
                          ]
                        )
                    )
                    (command.Simple
                      words: [{(cat)}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_Great val:'>' span_id:9809)
                          fd: -1
                          arg_word: {(/etc/systemd/system/) ($ Id.VSub_DollarName '$SYSTEMD_UNIT')}
                        )
                        (redir.HereDoc
                          op: (Token id:Id.Redir_DLess val:'<<' span_id:9814)
                          fd: -1
                          here_begin: {(__EOF__)}
                          here_end_span_id: 9835
                          stdin_parts: [
                            ('[Unit]\n')
                            ('Description=Sandstorm server\n')
                            ('After=local-fs.target remote-fs.target network.target\n')
                            ('Requires=local-fs.target remote-fs.target network.target\n')
                            ('\n')
                            ('[Service]\n')
                            ('Type=forking\n')
                            ('ExecStart=')
                            ($ Id.VSub_DollarName '$PWD')
                            ('/sandstorm start\n')
                            ('ExecStop=')
                            ($ Id.VSub_DollarName '$PWD')
                            ('/sandstorm stop\n')
                            ('\n')
                            ('[Install]\n')
                            ('WantedBy=multi-user.target\n')
                          ]
                        )
                      ]
                    )
                    (C {(systemctl)} {(enable)} {(sandstorm)})
                    (C {(systemctl)} {(start)} {(sandstorm)})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:STARTED_SANDSTORM)
                          op: assign_op.Equal
                          rhs: {(DQ (yes))}
                          spids: [9851]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: configure_sysvinit_init_system
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-e)} {(/etc/init.d/sandstorm)} 
                                  {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:9893)
                            )
                          ]
                          action: [
                            (command.AndOr
                              ops: [Id.Op_DPipe]
                              children: [(C {(service)} {(sandstorm)} {(stop)}) (C {(true)})]
                            )
                          ]
                          spids: [9883 9895]
                        )
                      ]
                    )
                    (command.Simple
                      words: [{(cat)}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_Great val:'>' span_id:9924)
                          fd: -1
                          arg_word: {(/etc/init.d/sandstorm)}
                        )
                        (redir.HereDoc
                          op: (Token id:Id.Redir_DLess val:'<<' span_id:9928)
                          fd: -1
                          here_begin: {(__EOF__)}
                          here_end_span_id: 9983
                          stdin_parts: [
                            ('#! /bin/bash\n')
                            ('### BEGIN INIT INFO\n')
                            ('# Provides:          sandstorm\n')
                            ('# Required-Start:    ')
                            (word_part.EscapedLiteral
                              token: (Token id:Id.Lit_EscapedChar val:'\\$' span_id:9936)
                            )
                            ('local_fs ')
                            (word_part.EscapedLiteral
                              token: (Token id:Id.Lit_EscapedChar val:'\\$' span_id:9938)
                            )
                            ('remote_fs ')
                            (word_part.EscapedLiteral
                              token: (Token id:Id.Lit_EscapedChar val:'\\$' span_id:9940)
                            )
                            ('networking ')
                            (word_part.EscapedLiteral
                              token: (Token id:Id.Lit_EscapedChar val:'\\$' span_id:9942)
                            )
                            ('syslog\n')
                            ('# Required-Stop:     ')
                            (word_part.EscapedLiteral
                              token: (Token id:Id.Lit_EscapedChar val:'\\$' span_id:9945)
                            )
                            ('local_fs ')
                            (word_part.EscapedLiteral
                              token: (Token id:Id.Lit_EscapedChar val:'\\$' span_id:9947)
                            )
                            ('remote_fs ')
                            (word_part.EscapedLiteral
                              token: (Token id:Id.Lit_EscapedChar val:'\\$' span_id:9949)
                            )
                            ('networking ')
                            (word_part.EscapedLiteral
                              token: (Token id:Id.Lit_EscapedChar val:'\\$' span_id:9951)
                            )
                            ('syslog\n')
                            ('# Default-Start:     2 3 4 5\n')
                            ('# Default-Stop:      0 1 6\n')
                            ('# Short-Description: starts Sandstorm personal cloud server\n')
                            ('### END INIT INFO\n')
                            ('\n')
                            ('DESC=')
                            (Id.Right_DoubleQuote '"')
                            ('Sandstorm server')
                            (Id.Right_DoubleQuote '"')
                            ('\n')
                            ('DAEMON=')
                            ($ Id.VSub_DollarName '$PWD')
                            ('/sandstorm\n')
                            ('\n')
                            (
'# The Sandstorm runner supports all the common init commands directly.\n'
                            )
                            ('# We use -a to set the program name to make help text look nicer.\n')
                            ('# This requires bash, though.\n')
                            ('exec -a ')
                            (Id.Right_DoubleQuote '"')
                            ('service sandstorm')
                            (Id.Right_DoubleQuote '"')
                            (' ')
                            (word_part.EscapedLiteral
                              token: (Token id:Id.Lit_EscapedChar val:'\\$' span_id:9975)
                            )
                            ('DAEMON ')
                            (Id.Right_DoubleQuote '"')
                            (word_part.EscapedLiteral
                              token: (Token id:Id.Lit_EscapedChar val:'\\$' span_id:9978)
                            )
                            ('@')
                            (Id.Right_DoubleQuote '"')
                            ('\n')
                          ]
                        )
                      ]
                    )
                    (C {(chmod)} {(Id.Lit_Other '+') (x)} {(/etc/init.d/sandstorm)})
                    (C {(update-rc.d)} {(sandstorm)} {(defaults)})
                    (C {(service)} {(sandstorm)} {(start)})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:STARTED_SANDSTORM)
                          op: assign_op.Equal
                          rhs: {(DQ (yes))}
                          spids: [10017]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: generate_admin_token
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ (${ Id.VSub_Name ALLOW_DEV_ACCOUNTS))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:10054)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:10059)
                            )
                          ]
                          spids: [10036 10056]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:ADMIN_TOKEN span_id:10084)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:10091)
                            )
                          ]
                          action: [
                            (C {(local)} 
                              {(Id.Lit_VarLike 'TMPFILENAME=') 
                                (DQ 
                                  (command_sub
                                    left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:10100)
                                    command_list: 
                                      (command.CommandList
                                        children: [
                                          (C {(mktemp)} {(./var/sandstorm/adminTokenTmp.XXXXXXXXXX)})
                                        ]
                                      )
                                  )
                                )
                              }
                            )
                            (command.Simple
                              words: [{(echo)} {(-n)} {(DQ ($ Id.VSub_DollarName '$ADMIN_TOKEN'))}]
                              redirects: [
                                (redir.Redir
                                  op: (Token id:Id.Redir_Great val:'>' span_id:10116)
                                  fd: -1
                                  arg_word: {(DQ ($ Id.VSub_DollarName '$TMPFILENAME'))}
                                )
                              ]
                            )
                            (C {(local)} 
                              {(Id.Lit_VarLike 'FILENAME=') (DQ (./var/sandstorm/adminToken))}
                            )
                            (C {(mv)} {(DQ ($ Id.VSub_DollarName '$TMPFILENAME'))} 
                              {(DQ ($ Id.VSub_DollarName '$FILENAME'))}
                            )
                            (C {(chmod)} {(0640)} {(DQ ($ Id.VSub_DollarName '$FILENAME'))})
                            (C {(chgrp)} {(DQ ($ Id.VSub_DollarName '$SERVER_USER'))} 
                              {(DQ ($ Id.VSub_DollarName '$FILENAME'))}
                            )
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:10162)
                            )
                          ]
                          spids: [10074 10093]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:ADMIN_TOKEN)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:10170)
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(./sandstorm)} {(admin-token)} {(--quiet)})]
                                  )
                              )
                            }
                          spids: [10169]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: print_success
              body: 
                (command.BraceGroup
                  children: [
                    (C {(echo)} {(DQ )})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$SANDSTORM_NEEDS_TO_BE_STARTED'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:10210)
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ('Installation complete. To start your server now, run:'))})
                            (C {(echo)} {(DQ ('  ') ($ Id.VSub_DollarName '$DIR') ('/sandstorm start'))})
                            (C {(echo)} {(DQ ("Once that's done, visit this link to start using it:"))})
                          ]
                          spids: [10194 10212]
                        )
                      ]
                      else_action: [
                        (C {(echo)} {(-n)} {(DQ ('Your server is now online! '))})
                        (command.If
                          arms: [
                            (if_arm
                              cond: [
                                (command.Sentence
                                  child: 
                                    (C {(Id.Lit_LBracket '[')} 
                                      {(DQ (${ Id.VSub_Name SANDCATS_HTTPS_SUCCESSFUL))} {(Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                    )
                                  terminator: (Token id:Id.Op_Semi val:';' span_id:10268)
                                )
                              ]
                              action: [
                                (C {(echo)} {(DQ ('It should work immediately if you use Chrome.'))})
                              ]
                              spids: [10250 10270]
                            )
                          ]
                        )
                        (C {(echo)} {(DQ ('Visit this link to start using it:'))})
                      ]
                    )
                    (C {(echo)} {(DQ )})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: (Token id:Id.VSub_Name val:ADMIN_TOKEN span_id:10319)
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:10326)
                            )
                          ]
                          action: [
                            (C {(echo)} 
                              {
                                (DQ ('  ') 
                                  (braced_var_sub
                                    token: (Token id:Id.VSub_Name val:BASE_URL span_id:10336)
                                    suffix_op: 
                                      (suffix_op.Unary
                                        op_id: Id.VTest_ColonHyphen
                                        arg_word: {('(unknown; bad config)')}
                                      )
                                  ) (/setup/token/) ($ Id.VSub_DollarName '$ADMIN_TOKEN')
                                )
                              }
                            )
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'NOTE: This URL expires in 15 minutes. You can generate a new setup URL by running'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ("'sudo sandstorm admin-token' from the command line."))})
                          ]
                          spids: [10309 10328]
                        )
                      ]
                      else_action: [
                        (C {(echo)} 
                          {
                            (DQ ('  ') 
                              (braced_var_sub
                                token: (Token id:Id.VSub_Name val:BASE_URL span_id:10373)
                                suffix_op: 
                                  (suffix_op.Unary
                                    op_id: Id.VTest_ColonHyphen
                                    arg_word: {('(unknown; bad config)')}
                                  )
                              ) (/)
                            )
                          }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ (${ Id.VSub_Name ALLOW_DEV_ACCOUNTS))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:10402)
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
"NOTE: Use the passwordless admin account called Alice for convenient dev login (since you have 'dev accounts' enabled)."
                                  )
                                )
                              }
                            )
                          ]
                          spids: [10384 10404]
                        )
                      ]
                    )
                    (C {(echo)} {(DQ )})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} 
                                  {(DQ (${ Id.VSub_Name SANDCATS_HTTPS_SUCCESSFUL))} {(Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:10448)
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'(If your browser shows you an OCSP error, wait 10 minutes for it to auto-resolve'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('and try Chrome until then.)'))})
                          ]
                          spids: [10430 10450]
                        )
                      ]
                    )
                    (C {(echo)})
                    (C {(echo)} {(DQ ('To learn how to control the server, run:'))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:10502)
                            )
                          ]
                          action: [(C {(echo)} {(DQ ('  sandstorm help'))})]
                          spids: [10486 10504]
                        )
                      ]
                      else_action: [
                        (C {(echo)} {(DQ ('  ') ($ Id.VSub_DollarName '$DIR') ('/sandstorm help'))})
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_provide_help
              body: 
                (command.BraceGroup
                  children: [
                    (C {(echo)} 
                      {
                        (DQ 
                          (
'Sandcats.io is a free dynamic DNS service run by the Sandstorm development team.'
                          )
                        )
                      }
                    )
                    (C {(echo)} {(DQ )})
                    (C {(echo)} {(DQ ('You can:'))})
                    (C {(echo)} {(DQ )})
                    (C {(echo)} {(DQ ('* Read more about it at:'))})
                    (C {(echo)} 
                      {(DQ ('  https://github.com/sandstorm-io/sandstorm/wiki/Sandcats-dynamic-DNS'))}
                    )
                    (C {(echo)} {(DQ )})
                    (C {(echo)} 
                      {(DQ ('* Recover access to a domain you once registered with sandcats'))}
                    )
                    (C {(echo)} {(DQ )})
                    (C {(echo)} {(DQ ('* Just press enter to go to the previous question.'))})
                    (C {(sandcats_recover_domain)})
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_recover_domain
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:DESIRED_SANDCATS_NAME)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:10617)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt)} 
                                        {(DQ ('What Sandcats subdomain do you want to recover?'))} {(DQ (none))}
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [10616]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (none))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:10651)
                            )
                          ]
                          action: [
                            (C {(sandcats_register_name)})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:10659)
                            )
                          ]
                          spids: [10635 10653]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.DBracket
                                  expr: 
                                    (bool_expr.Binary
                                      op_id: Id.BoolBinary_EqualTilde
                                      left: {($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME')}
                                      right: {(Id.Lit_Other '[') (Id.Lit_Other .) (Id.Lit_Other ']')}
                                    )
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:10684)
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {(DQ ('You entered: ') ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME'))}
                            )
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'but this function just wants the name of your subdomain, not including any dot characters.'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('Please try again.'))})
                            (C {(echo)} {(DQ )})
                            (C {(sandcats_recover_domain)})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:10732)
                            )
                          ]
                          spids: [10670 10686]
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (DQ 
                          (
'OK. We will send a recovery token to the email address on file. Type no to abort.'
                          )
                        )
                      }
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:OK_TO_CONTINUE)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:10747)
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(prompt)} {(DQ ('OK to continue?'))} {(DQ (yes))})]
                                  )
                              )
                            }
                          spids: [10746]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (no))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$OK_TO_CONTINUE'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:10776)
                            )
                          ]
                          action: [
                            (C {(sandcats_register_name)})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:10784)
                            )
                          ]
                          spids: [10760 10778]
                        )
                      ]
                    )
                    (C {(local)} 
                      {(Id.Lit_VarLike 'LOG_PATH=') (DQ (var/sandcats/sendrecoverytoken-log))}
                    )
                    (C {(touch)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (C {(chmod)} {(0640)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:10820)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                        {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('rawHostname=') 
                                            ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME')
                                          )
                                        } {(--output)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))} {(-w)} 
                                        {
                                          (SQ 
                                            (Token
                                              id: Id.Lit_Chars
                                              val: '%{http_code}'
                                              span_id: 10875
                                            )
                                          )
                                        } {(-H)} {(SQ (Token id:Id.Lit_Chars val:'X-Sand: cats' span_id:10883))} {(-H)} 
                                        {(DQ ('Accept: text/plain'))} {(DQ (${ Id.VSub_Name SANDCATS_API_BASE) (/sendrecoverytoken))}
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [10819]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (200))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:10923)
                            )
                          ]
                          action: [
                            (C {(error)} 
                              {
                                (DQ 
                                  (command_sub
                                    left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:10931)
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(cat)} {($ Id.VSub_DollarName '$LOG_PATH')})]
                                      )
                                  )
                                )
                              }
                            )
                            (C {(sandcats_recover_domain)})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:10942)
                            )
                          ]
                          spids: [10906 10925]
                        )
                      ]
                    )
                    (C {(cat)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (C {(echo)} {(SQ )})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:TOKEN)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:10975)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt)} 
                                        {
                                          (DQ 
                                            ('Please enter the token that we sent to you by email.')
                                          )
                                        } {(SQ )}
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [10974]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-z)} {(DQ ($ Id.VSub_DollarName '$TOKEN'))} 
                                  {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:11004)
                            )
                          ]
                          action: [
                            (C {(error)} {(DQ ('Empty tokens are not valid.'))})
                            (C {(sandcats_recover_domain)})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:11019)
                            )
                          ]
                          spids: [10992 11006]
                        )
                      ]
                    )
                    (C {(local)} {(Id.Lit_VarLike 'LOG_PATH=') (DQ (var/sandcats/recover-log))})
                    (C {(touch)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (C {(chmod)} {(0640)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:11071)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                        {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('rawHostname=') 
                                            ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME')
                                          )
                                        } {(--data-urlencode)} {(DQ ('recoveryToken=') ($ Id.VSub_DollarName '$TOKEN'))} {(--output)} 
                                        {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))} {(-w)} {(SQ (Token id:Id.Lit_Chars val:'%{http_code}' span_id:11135))} {(-H)} 
                                        {
                                          (SQ 
                                            (Token
                                              id: Id.Lit_Chars
                                              val: 'X-Sand: cats'
                                              span_id: 11143
                                            )
                                          )
                                        } {(-H)} {(DQ ('Accept: text/plain'))} {(--cert)} {(var/sandcats/id_rsa.private_combined)} 
                                        {(DQ (${ Id.VSub_Name SANDCATS_API_BASE) (/recover))}
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [11070]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (200))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:11189)
                            )
                          ]
                          action: [
                            (C {(error)} 
                              {
                                (DQ 
                                  (command_sub
                                    left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:11197)
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(cat)} {($ Id.VSub_DollarName '$LOG_PATH')})]
                                      )
                                  )
                                )
                              }
                            )
                            (C {(sandcats_recover_domain)})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:11208)
                            )
                          ]
                          spids: [11172 11191]
                        )
                      ]
                    )
                    (C {(cat)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (C {(echo)} {(SQ )})
                    (C {(local)} {(Id.Lit_VarLike 'LOG_PATH=') (DQ (var/sandcats/update-log))})
                    (C {(touch)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (C {(chmod)} {(0640)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:11282)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                        {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('rawHostname=') 
                                            ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME')
                                          )
                                        } {(--output)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))} {(-w)} 
                                        {
                                          (SQ 
                                            (Token
                                              id: Id.Lit_Chars
                                              val: '%{http_code}'
                                              span_id: 11337
                                            )
                                          )
                                        } {(-H)} {(SQ (Token id:Id.Lit_Chars val:'X-Sand: cats' span_id:11345))} {(-H)} 
                                        {(DQ ('Accept: text/plain'))} {(--cert)} {(var/sandcats/id_rsa.private_combined)} {(DQ (${ Id.VSub_Name SANDCATS_API_BASE) (/update))}
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [11281]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (200))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:11391)
                            )
                          ]
                          action: [
                            (C {(error)} 
                              {
                                (DQ 
                                  (command_sub
                                    left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:11399)
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(cat)} {($ Id.VSub_DollarName '$LOG_PATH')})]
                                      )
                                  )
                                )
                              }
                            )
                            (C {(sandcats_recover_domain)})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:11410)
                            )
                          ]
                          spids: [11374 11393]
                        )
                      ]
                    )
                    (C {(cat)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (C {(echo)} {(SQ )})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL)
                          op: assign_op.Equal
                          rhs: {(DQ (yes))}
                          spids: [11439]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (DQ (${ Id.VSub_Name DESIRED_SANDCATS_NAME) (.) 
                                (${ Id.VSub_Name SANDCATS_BASE_DOMAIN)
                              )
                            }
                          spids: [11445]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                          op: assign_op.Equal
                          rhs: {(DQ (yes))}
                          spids: [11457]
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (DQ ("Congratulations! You're all configured to use ") 
                          (${ Id.VSub_Name DESIRED_SANDCATS_NAME) (.) (${ Id.VSub_Name SANDCATS_BASE_DOMAIN) (.)
                        )
                      }
                    )
                    (C {(echo)} 
                      {
                        (DQ ('Your credentials to use it are in ') 
                          (command_sub
                            left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:11482)
                            command_list: 
                              (command.CommandList
                                children: [(C {(readlink)} {(-f)} {(var/sandcats)})]
                              )
                          ) ('; consider making a backup.')
                        )
                      }
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_registerreserved
              body: 
                (command.BraceGroup
                  children: [
                    (C {(echo)} {(DQ ('Registering your pre-reserved domain.'))})
                    (C {(local)} {(LOG_PATH)})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:LOG_PATH)
                          op: assign_op.Equal
                          rhs: {(DQ (var/sandcats/registerreserved-log))}
                          spids: [11514]
                        )
                      ]
                    )
                    (C {(touch)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (C {(chmod)} {(0640)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:11537)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                        {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('domainReservationToken=') 
                                            ($ Id.VSub_DollarName 
'$SANDCATS_DOMAIN_RESERVATION_TOKEN'
                                            )
                                          )
                                        } {(--data-urlencode)} {(DQ ('rawHostname=') ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME'))} 
                                        {(--output)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))} {(-w)} 
                                        {
                                          (SQ 
                                            (Token
                                              id: Id.Lit_Chars
                                              val: '%{http_code}'
                                              span_id: 11601
                                            )
                                          )
                                        } {(-H)} {(SQ (Token id:Id.Lit_Chars val:'X-Sand: cats' span_id:11609))} {(-H)} 
                                        {(DQ ('Accept: text/plain'))} {(--cert)} {(var/sandcats/id_rsa.private_combined)} 
                                        {(DQ (${ Id.VSub_Name SANDCATS_API_BASE) (/registerreserved))}
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [11536]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (C {(Id.Lit_LBracket '[')} {(DQ (200))} {(Id.Lit_Equals '=')} 
                              {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {(Id.Lit_RBracket ']')}
                            )
                          ]
                          action: [
                            (C {(cat)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                            (C {(echo)} {(SQ )})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (DQ (${ Id.VSub_Name DESIRED_SANDCATS_NAME) (.) 
                                        (${ Id.VSub_Name SANDCATS_BASE_DOMAIN)
                                      )
                                    }
                                  spids: [11691]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [11703]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [11709]
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('Congratulations! We have registered your ') 
                                  (${ Id.VSub_Name DESIRED_SANDCATS_NAME) (.) (${ Id.VSub_Name SANDCATS_BASE_DOMAIN) (' name.')
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ ('Your credentials to use it are in ') 
                                  (command_sub
                                    left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:11734)
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(readlink)} {(-f)} {(var/sandcats)})]
                                      )
                                  ) ('; consider making a backup.')
                                )
                              }
                            )
                          ]
                          spids: [11638 11655]
                        )
                      ]
                      else_action: [
                        (C {(fail)} {(DQ (E_SANDCATS_REGISTER_RESERVED_SRV_FAIL))} 
                          {
                            (DQ 
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:11771)
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(cat)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})]
                                  )
                              )
                            )
                          }
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_register_name
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SANDCATS_API_BASE)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (DQ 
                                (braced_var_sub
                                  token: 
                                    (Token
                                      id: Id.VSub_Name
                                      val: OVERRIDE_SANDCATS_API_BASE
                                      span_id: 11808
                                    )
                                  suffix_op: 
                                    (suffix_op.Unary
                                      op_id: Id.VTest_ColonHyphen
                                      arg_word: 
                                        {('https:') (Id.Lit_Slash /) (Id.Lit_Slash /) (sandcats.io)}
                                    )
                                )
                              )
                            }
                          spids: [11805]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SANDCATS_CURL_PARAMS)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (DQ 
                                (braced_var_sub
                                  token: 
                                    (Token
                                      id: Id.VSub_Name
                                      val: OVERRIDE_SANDCATS_CURL_PARAMS
                                      span_id: 11821
                                    )
                                  suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                )
                              )
                            }
                          spids: [11818]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(Id.KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: 
                                          (Token
                                            id: Id.VSub_Name
                                            val: SANDCATS_DOMAIN_RESERVATION_TOKEN
                                            span_id: 11846
                                          )
                                        suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:11853)
                            )
                          ]
                          action: [
                            (C {(sandcats_registerreserved)})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:11861)
                            )
                          ]
                          spids: [11836 11855]
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (DQ 
                          (
'Choose your desired Sandcats subdomain (alphanumeric, max 20 characters).'
                          )
                        )
                      }
                    )
                    (C {(echo)} {(DQ ('Type the word none to skip this step, or help for help.'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:DESIRED_SANDCATS_NAME)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:11883)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt)} 
                                        {
                                          (DQ ('What *.') (${ Id.VSub_Name SANDCATS_BASE_DOMAIN) 
                                            (' subdomain would you like?')
                                          )
                                        } {(SQ )}
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [11882]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-z)} 
                                  {(DQ ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:11920)
                            )
                          ]
                          action: [
                            (C {(sandcats_register_name)})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:11928)
                            )
                          ]
                          spids: [11908 11922]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (none))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:11955)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:11960)
                            )
                          ]
                          spids: [11939 11957]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (help))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:11987)
                            )
                          ]
                          action: [
                            (C {(sandcats_provide_help)})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:11995)
                            )
                          ]
                          spids: [11971 11989]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Pipeline
                                  children: [
                                    (command.DBracket
                                      expr: 
                                        (bool_expr.Binary
                                          op_id: Id.BoolBinary_EqualTilde
                                          left: {($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME')}
                                          right: 
                                            {(Id.Lit_Other '^') (Id.Lit_Other '[') (0-9a-zA-Z-) 
                                              (Id.Lit_Other ']') (Id.Lit_Other '{') (1) (Id.Lit_Other ',') (20) (Id.Lit_Other '}') (Id.Lit_Other '$')
                                            }
                                        )
                                    )
                                  ]
                                  negated: T
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:12033)
                            )
                          ]
                          action: [
                            (C {(sandcats_register_name)})
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:12041)
                            )
                          ]
                          spids: [12010 12035]
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (DQ 
                          (
'We need your email on file so we can help you recover your domain if you lose access. No spam.'
                          )
                        )
                      }
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SANDCATS_REGISTRATION_EMAIL)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:12064)
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(prompt)} {(DQ ('Enter your email address:'))} {(DQ )})]
                                  )
                              )
                            }
                          spids: [12063]
                        )
                      ]
                    )
                    (command.WhileUntil
                      keyword: (Token id:Id.KW_While val:while span_id:12081)
                      cond: [
                        (command.Sentence
                          child: 
                            (C {(Id.Lit_LBracket '[')} {(DQ )} {(Id.Lit_Equals '=')} 
                              {(DQ ($ Id.VSub_DollarName '$SANDCATS_REGISTRATION_EMAIL'))} {(Id.Lit_RBracket ']')}
                            )
                          terminator: (Token id:Id.Op_Semi val:';' span_id:12096)
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'For the DNS service, we really do need an email address. To cancel, type: Ctrl-C.'
                                  )
                                )
                              }
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDCATS_REGISTRATION_EMAIL)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: 
                                          (Token
                                            id: Id.Left_DollarParen
                                            val: '$('
                                            span_id: 12109
                                          )
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(prompt)} {(DQ ('Enter your email address:'))} {(DQ )})
                                            ]
                                          )
                                      )
                                    }
                                  spids: [12108]
                                )
                              ]
                            )
                          ]
                        )
                    )
                    (C {(echo)} {(DQ ('Registering your domain.'))})
                    (C {(local)} {(LOG_PATH)})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:LOG_PATH)
                          op: assign_op.Equal
                          rhs: {(DQ (var/sandcats/register-log))}
                          spids: [12137]
                        )
                      ]
                    )
                    (C {(touch)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (C {(chmod)} {(0640)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:12160)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                        {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('rawHostname=') 
                                            ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME')
                                          )
                                        } {(--data-urlencode)} {(DQ ('email=') ($ Id.VSub_DollarName '$SANDCATS_REGISTRATION_EMAIL'))} 
                                        {(--output)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))} {(-w)} 
                                        {
                                          (SQ 
                                            (Token
                                              id: Id.Lit_Chars
                                              val: '%{http_code}'
                                              span_id: 12224
                                            )
                                          )
                                        } {(-H)} {(SQ (Token id:Id.Lit_Chars val:'X-Sand: cats' span_id:12232))} {(-H)} 
                                        {(DQ ('Accept: text/plain'))} {(--cert)} {(var/sandcats/id_rsa.private_combined)} 
                                        {(DQ (${ Id.VSub_Name SANDCATS_API_BASE) (/register))}
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [12159]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (C {(Id.Lit_LBracket '[')} {(DQ (200))} {(Id.Lit_Equals '=')} 
                              {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {(Id.Lit_RBracket ']')}
                            )
                          ]
                          action: [
                            (C {(cat)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                            (C {(echo)} {(SQ )})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                                  op: assign_op.Equal
                                  rhs: 
                                    {
                                      (DQ (${ Id.VSub_Name DESIRED_SANDCATS_NAME) (.) 
                                        (${ Id.VSub_Name SANDCATS_BASE_DOMAIN)
                                      )
                                    }
                                  spids: [12314]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [12326]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [12332]
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('Congratulations! We have registered your ') 
                                  (${ Id.VSub_Name DESIRED_SANDCATS_NAME) (.) (${ Id.VSub_Name SANDCATS_BASE_DOMAIN) (' name.')
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ ('Your credentials to use it are in ') 
                                  (command_sub
                                    left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:12357)
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(readlink)} {(-f)} {(var/sandcats)})]
                                      )
                                  ) ('; consider making a backup.')
                                )
                              }
                            )
                          ]
                          spids: [12261 12278]
                        )
                      ]
                      else_action: [
                        (C {(error)} 
                          {
                            (DQ 
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:12378)
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(cat)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})]
                                  )
                              )
                            )
                          }
                        )
                        (C {(sandcats_register_name)})
                        (command.ControlFlow
                          token: (Token id:Id.ControlFlow_Return val:return span_id:12391)
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_configure_https
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$SANDCATS_GETCERTIFICATE'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:12431)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:12436)
                            )
                          ]
                          spids: [12414 12433]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ ($ Id.VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:12464)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:12469)
                            )
                          ]
                          spids: [12447 12466]
                        )
                      ]
                    )
                    (C {(echo)} {(DQ ("Now we're going to auto-configure HTTPS for your server."))})
                    (C {(echo)} {(DQ )})
                    (C {(echo)} 
                      {(DQ ('* This will take about 30 seconds, and needs no input from you.'))}
                    )
                    (C {(echo)} {(DQ ('* Thanks to GlobalSign for their help making this happen.'))})
                    (C {(echo)} {(DQ )})
                    (C {(local)} {(Id.Lit_VarLike 'HTTPS_BASE_DIR=') (DQ (var/sandcats/https))})
                    (C {(local)} 
                      {(Id.Lit_VarLike 'HTTPS_CONFIG_DIR=') 
                        (DQ ($ Id.VSub_DollarName '$HTTPS_BASE_DIR') (/) 
                          ($ Id.VSub_DollarName '$SS_HOSTNAME')
                        )
                      }
                    )
                    (C {(mkdir)} {(-p)} {(-m)} {(0700)} {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR'))})
                    (C {(chmod)} {(0700)} {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR'))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:12615)
                            )
                          ]
                          action: [
                            (C {(chown)} {(-R)} 
                              {(DQ ($ Id.VSub_DollarName '$SERVER_USER')) (Id.Lit_Other ':') 
                                (DQ ($ Id.VSub_DollarName '$SERVER_USER'))
                              } {(DQ ($ Id.VSub_DollarName '$HTTPS_BASE_DIR'))}
                            )
                          ]
                          spids: [12599 12617]
                        )
                      ]
                    )
                    (C {(echo)} {(DQ ('Generating certificate request...'))})
                    (command.Simple
                      words: [
                        {(openssl)}
                        {(req)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:12678) command_list:(command.NoOp))}
                        {(-nodes)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:12689) command_list:(command.NoOp))}
                        {(-newkey)}
                        {(rsa) (Id.Lit_Other ':') (4096)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:12704) command_list:(command.NoOp))}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:12713) command_list:(command.NoOp))}
                        {(-subj)}
                        {(DQ ('/CN=*.') (${ Id.VSub_Name SS_HOSTNAME) (/))}
                        {(-keyout)}
                        {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR')) (/0)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:12741) command_list:(command.NoOp))}
                        {(-out)}
                        {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR')) (/0.csr)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:12757) command_list:(command.NoOp))}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:12769) command_list:(command.NoOp))}
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_Great val:'2>' span_id:12766)
                          fd: 2
                          arg_word: {(/dev/null)}
                        )
                      ]
                    )
                    (C {(chmod)} {(0600)} {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR')) (/0)})
                    (C {(chmod)} {(0600)} {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR')) (/0.csr)})
                    (C {(echo)} {(DQ ('Requesting certificate (BE PATIENT)...'))})
                    (C {(local)} {(LOG_PATH)})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:LOG_PATH)
                          op: assign_op.Equal
                          rhs: {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR') (/0.response-json))}
                          spids: [12835]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:12843)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(60)} 
                                        {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('rawHostname=') 
                                            ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME')
                                          )
                                        } {(--data-urlencode)} 
                                        {
                                          (DQ ('certificateSigningRequest=') 
                                            (command_sub
                                              left_token: 
                                                (Token
                                                  id: Id.Left_DollarParen
                                                  val: '$('
                                                  span_id: 12891
                                                )
                                              command_list: 
                                                (command.CommandList
                                                  children: [
                                                    (C {(cat)} 
                                                      {
                                                        (DQ 
                                                          ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR') (/0.csr)
                                                        )
                                                      }
                                                    )
                                                  ]
                                                )
                                            )
                                          )
                                        } {(--output)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))} {(-w)} 
                                        {
                                          (SQ 
                                            (Token
                                              id: Id.Lit_Chars
                                              val: '%{http_code}'
                                              span_id: 12914
                                            )
                                          )
                                        } {(-H)} {(SQ (Token id:Id.Lit_Chars val:'X-Sand: cats' span_id:12922))} {(--cert)} 
                                        {(var/sandcats/id_rsa.private_combined)} 
                                        {
                                          (DQ (${ Id.VSub_Name SANDCATS_API_BASE) (/) 
                                            (braced_var_sub
                                              token: 
                                                (Token
                                                  id: Id.VSub_Name
                                                  val: OVERRIDE_SANDCATS_GETCERTIFICATE_API_PATH
                                                  span_id: 12939
                                                )
                                              suffix_op: 
                                                (suffix_op.Unary
                                                  op_id: Id.VTest_ColonHyphen
                                                  arg_word: {(getcertificate)}
                                                )
                                            )
                                          )
                                        }
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [12842]
                        )
                      ]
                    )
                    (C {(chmod)} {(0600)} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))})
                    (C {(chown)} 
                      {(DQ ($ Id.VSub_DollarName '$SERVER_USER')) (Id.Lit_Other ':') 
                        (DQ ($ Id.VSub_DollarName '$SERVER_USER'))
                      } {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR') (/)) (Id.Lit_Star '*')}
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (C {(Id.Lit_LBracket '[')} {(DQ (200))} {(Id.Lit_Equals '=')} 
                              {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {(Id.Lit_RBracket ']')}
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ('Successfully auto-configured HTTPS!'))})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDCATS_HTTPS_SUCCESSFUL)
                                  op: assign_op.Equal
                                  rhs: {(DQ (yes))}
                                  spids: [13019]
                                )
                              ]
                            )
                          ]
                          spids: [12980 12997]
                        )
                      ]
                      else_action: [
                        (C {(error)} 
                          {
                            (DQ 
                              (
'Some part of HTTPS autoconfiguration failed. Log data available in '
                              ) ($ Id.VSub_DollarName '$LOG_PATH')
                            )
                          }
                        )
                        (command.ControlFlow
                          token: (Token id:Id.ControlFlow_Return val:return span_id:13040)
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: wait_for_server_bind_to_its_port
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} 
                                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ (${ Id.VSub_Name STARTED_SANDSTORM))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:13078)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:13083)
                            )
                          ]
                          spids: [13059 13080]
                        )
                      ]
                    )
                    (C {(local)} 
                      {(Id.Lit_VarLike 'PORT_TO_CHECK=') 
                        (DQ 
                          (braced_var_sub
                            token: (Token id:Id.VSub_Name val:HTTPS_PORT span_id:13107)
                            suffix_op: 
                              (suffix_op.Unary
                                op_id: Id.VTest_ColonHyphen
                                arg_word: {($ Id.VSub_DollarName '$PORT')}
                              )
                          )
                        )
                      }
                    )
                    (C {(echo)} {(-n)} 
                      {(DQ ('Your server is coming online. Waiting up to 90 seconds...'))}
                    )
                    (C {(local)} {(Id.Lit_VarLike 'ONLINE_YET=') (DQ (no))})
                    (command.ForEach
                      iter_name: waited_n_seconds
                      iter_words: [
                        {
                          (command_sub
                            left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:13137)
                            command_list: (command.CommandList children:[(C {(seq)} {(0)} {(89)})])
                          )
                        }
                      ]
                      do_arg_iter: F
                      body: 
                        (command.DoGroup
                          children: [
                            (command.AndOr
                              ops: [Id.Op_DAmp]
                              children: [
                                (C {(is_port_bound)} {(DQ (${ Id.VSub_Name BIND_IP))} 
                                  {(DQ (${ Id.VSub_Name PORT_TO_CHECK))}
                                )
                                (command.ShAssignment
                                  pairs: [
                                    (assign_pair
                                      lhs: (sh_lhs_expr.Name name:ONLINE_YET)
                                      op: assign_op.Equal
                                      rhs: {(DQ (yes))}
                                      spids: [13165]
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Id.Lit_LBracket '[')} 
                                          {(DQ ($ Id.VSub_DollarName '$ONLINE_YET'))} {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                        )
                                      terminator: (Token id:Id.Op_Semi val:';' span_id:13188)
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} {(SQ )})
                                    (command.ControlFlow
                                      token: (Token id:Id.ControlFlow_Break val:break span_id:13199)
                                    )
                                  ]
                                  spids: [13171 13190]
                                )
                              ]
                            )
                            (C {(echo)} {(-n)} {(DQ (.))})
                            (C {(sleep)} {(1)})
                          ]
                        )
                    )
                    (command.AndOr
                      ops: [Id.Op_DAmp]
                      children: [
                        (C {(is_port_bound)} {(DQ (${ Id.VSub_Name BIND_IP))} 
                          {(DQ (${ Id.VSub_Name PORT_TO_CHECK))}
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:ONLINE_YET)
                              op: assign_op.Equal
                              rhs: {(DQ (yes))}
                              spids: [13243]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ ($ Id.VSub_DollarName '$ONLINE_YET'))} 
                                  {(Id.Lit_Equals '=') (Id.Lit_Equals '=')} {(DQ (yes))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:13266)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:13271)
                            )
                          ]
                          spids: [13250 13268]
                        )
                      ]
                      else_action: [
                        (C {(fail)} {(DQ (E_NEVER_LISTENED))} 
                          {(DQ ('Your server never started listening.'))}
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_generate_keys
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-f)} 
                                  {(var/sandcats/id_rsa.private_combined)} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:13314)
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Return val:return span_id:13319)
                            )
                          ]
                          spids: [13304 13316]
                        )
                      ]
                    )
                    (C {(echo)} {(-n)} {(SQ (Token id:Id.Lit_Chars val:... span_id:13339))})
                    (C {(mkdir)} {(-p)} {(-m)} {(0700)} {(var/sandcats)})
                    (C {(chmod)} {(0700)} {(var/sandcats)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:13395)
                            )
                          ]
                          action: [
                            (C {(chown)} 
                              {(DQ ($ Id.VSub_DollarName '$SERVER_USER')) (Id.Lit_Other ':') 
                                (DQ ($ Id.VSub_DollarName '$SERVER_USER'))
                              } {(var/sandcats)}
                            )
                          ]
                          spids: [13379 13397]
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(openssl)}
                        {(req)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:13435) command_list:(command.NoOp))}
                        {(-new)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:13446) command_list:(command.NoOp))}
                        {(-newkey)}
                        {(rsa) (Id.Lit_Other ':') (4096)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:13461) command_list:(command.NoOp))}
                        {(-days)}
                        {(3650)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:13474) command_list:(command.NoOp))}
                        {(-nodes)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:13485) command_list:(command.NoOp))}
                        {(-x509)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:13496) command_list:(command.NoOp))}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:13505) command_list:(command.NoOp))}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:13514) command_list:(command.NoOp))}
                        {(-subj)}
                        {(DQ ('/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd'))}
                        {(-keyout)}
                        {(var/sandcats/id_rsa)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:13535) command_list:(command.NoOp))}
                        {(-out)}
                        {(var/sandcats/id_rsa.pub)}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:13548) command_list:(command.NoOp))}
                        {(command_sub left_token:(Token id:Id.Left_Backtick val:'`' span_id:13560) command_list:(command.NoOp))}
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_Great val:'2>' span_id:13557)
                          fd: 2
                          arg_word: {(/dev/null)}
                        )
                      ]
                    )
                    (command.Simple
                      words: [{(cat)} {(var/sandcats/id_rsa)} {(var/sandcats/id_rsa.pub)}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_Great val:'>' span_id:13583)
                          fd: -1
                          arg_word: {(var/sandcats/id_rsa.private_combined)}
                        )
                      ]
                    )
                    (C {(chmod)} {(0640)} {(var/sandcats/id_rsa)} {(var/sandcats/id_rsa.pub)} 
                      {(var/sandcats/id_rsa.private_combined)}
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(DQ (yes))} {(Id.Lit_Equals '=')} 
                                  {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:13633)
                            )
                          ]
                          action: [
                            (C {(chown)} 
                              {(DQ ($ Id.VSub_DollarName '$SERVER_USER')) (Id.Lit_Other ':') 
                                (DQ ($ Id.VSub_DollarName '$SERVER_USER'))
                              } 
                              (word.BracedTree
                                parts: [
                                  (var/sandcats/id_rsa)
                                  (word_part.BracedTuple
                                    words: [{} {(.pub)} {(.private_combined)}]
                                  )
                                ]
                              )
                            )
                          ]
                          spids: [13617 13635]
                        )
                      ]
                    )
                    (C {(echo)} {(-ne)} {(SQ (Token id:Id.Lit_Chars val:'\\r' span_id:13678))})
                  ]
                )
            )
            (C {(handle_args)} {(DQ ($ Id.VSub_At '$@'))})
            (C {(set_umask)})
            (C {(assert_on_terminal)})
            (C {(assert_linux_x86_64)})
            (C {(assert_usable_kernel)})
            (C {(detect_current_uid)})
            (C {(assert_dependencies)})
            (C {(assert_valid_bundle_file)})
            (C {(detect_init_system)})
            (C {(choose_install_mode)})
            (C {(maybe_enable_userns_sysctl)})
            (C {(choose_external_or_internal)})
            (C {(choose_install_dir)})
            (C {(choose_smtp_port)})
            (C {(load_existing_settings)})
            (C {(choose_server_user_if_needed)})
            (C {(create_server_user_if_needed)})
            (C {(configure_auto_updates)})
            (C {(configure_dev_accounts)})
            (C {(configure_hostnames)})
            (C {(save_config)})
            (C {(download_latest_bundle_and_extract_if_needed)})
            (C {(extract_bundle_if_provided)})
            (C {(make_runtime_directories)})
            (C {(generate_admin_token)})
            (C {(set_permissions)})
            (C {(install_sandstorm_symlinks)})
            (C {(ask_about_starting_at_boot)})
            (C {(configure_start_at_boot_if_desired)})
            (C {(wait_for_server_bind_to_its_port)})
            (C {(print_success)})
          ]
        )
    )
    (C {(_)} {(DQ ($ Id.VSub_Number '$0'))} {(DQ ($ Id.VSub_At '$@'))})
  ]
)