///|
fn ascii_is_letter(unit : UInt16) -> Bool {
  (unit >= 97 && unit <= 122) || (unit >= 65 && unit <= 90)
}

///|
fn ascii_is_digit(unit : UInt16) -> Bool {
  unit >= 48 && unit <= 57
}

///|
fn project_id_from_path(path : String) -> String {
  let source = base_name(path).to_lower()
  let builder = StringBuilder()
  let previous_separator = Ref(false)
  for index in 0.. String {
  let builder = StringBuilder()
  let capitalize = Ref(true)
  for index in 0..= 97 && char <= 122 {
      builder.write_char((char.to_int() - 32).unsafe_to_char())
      capitalize.val = false
    } else {
      builder.write_char(char.to_int().unsafe_to_char())
      capitalize.val = false
    }
  }
  let value = builder.to_string()
  if value == "" {
    "MoUIApp"
  } else {
    value
  }
}

///|
fn default_title(id : String) -> String {
  product_name(id)
}

///|
fn valid_project_id(id : String) -> Bool {
  if id == "" || !ascii_is_letter(id[0]) {
    return false
  }
  for index in 1.. Bool {
  if name == "" ||
    name.has_prefix("/") ||
    name.has_suffix("/") ||
    !name.contains("/") {
    return false
  }
  for index in 0.. Bool {
  if version == "" {
    return false
  }
  for index in 0.. Bool {
  if value == "" ||
    !value.contains(".") ||
    value.has_prefix(".") ||
    value.has_suffix(".") {
    return false
  }
  for index in 0.. String {
  value
  .replace_all(old="\\", new="\\\\")
  .replace_all(old="\"", new="\\\"")
  .replace_all(old="\n", new="\\n")
  .replace_all(old="\r", new="\\r")
}

///|
fn html_text(value : String) -> String {
  value
  .replace_all(old="&", new="&")
  .replace_all(old="<", new="<")
  .replace_all(old=">", new=">")
  .replace_all(old="\"", new=""")
}