let counter = 0 // Gove can't see where this is being used (10-2023)
const PAGE_URL = new URL(window.location)
const DEVELOPMENT_MODE = window.location.hostname==="127.0.0.1" || window.location.hostname==="localhost"
const PRODUCTION_MODE = !DEVELOPMENT_MODE
//const apps_script = {}
const post_list = {} // a direct link from the pageid to the entry in TOC.json
const menu_list = {} //  a direct link from the menu label to the entry in TOC.json

const sequence = {}
const section_map = {}
const sequence_array = []
let CURRENT_PAGE_ID //id of the currently loaded page
const DIAGRAM_NOTE_TIMEOUTS=[]// used for cancelling a note display if the user does not wait for a second
let book_config = null
let menu = null
let NEXT_LESSON_NUMBER=1// used to fill in the lesson nymbers in a table of contents.  done with the variable once the page loads


function download_text_file2(filename, text) {
  //log(filename)
  const element = document.createElement('a');
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  element.setAttribute('download', filename);

  element.style.display = 'none';
  document.body.appendChild(element);

  element.click();

  document.body.removeChild(element);
}



function Uint8ToString(u8a) {
  var CHUNK_SZ = 0x8000;
  var c = [];
  for (var i = 0; i < u8a.length; i += CHUNK_SZ) {
    c.push(String.fromCharCode.apply(null, u8a.subarray(i, i + CHUNK_SZ)));
  }
  return c.join("");
}
// Usage
//var u8 = new Uint8Array([65, 66, 67, 68]);
//var b64encoded = btoa(Uint8ToString(u8));








function set_gas_token(token) {
  // sets the token into local(or session) storage
  BookStorage.gasToken(token);
}
function get_gas_token() {
  // gets the token into local(or session) storage
  try{
    return BookStorage.gasToken();
  }catch{
    return "";
  }
  
}


  





function server_save(params){
  // saves a value to the server object store, if it is configured

}


function change_icon(p,  icon, color) {
  const icon_tag = p.querySelector("span")
  if(icon){
    icon_tag.innerHTML=icon
  }
  if(color!==undefined){
    icon_tag.style.color=color
  }
}

function append_to_message(p, text, color) {
  if(color===undefined){
    p.appendChild(document.createTextNode(text))
  }else{
    const span=document.createElement("span")
    span.style.color=color
    span.innerHTML=text
    p.appendChild(span)
  }
}

function succeed_message(p, text="passed."){
  const icon_tag = p.querySelector("span")
  if(icon_tag){
    change_icon(p,"check_box")
  }
  p.appendChild(document.createTextNode(text))
}

function no_message(p, text="no."){
  const icon_tag = p.querySelector("span")
  if(icon_tag){
    change_icon(p,"disabled_by_default")
  }
  p.appendChild(document.createTextNode(text))
}

function fail_message(p, text){
  const icon_tag = p.querySelector("span")
  if(icon_tag){
    change_icon(p,"cancel", "red")
  }
  const span=document.createElement("span")
  span.style.color="red"
  span.innerHTML="failed."
  p.appendChild(span)

  if(text){
    const m = add_message(text,"orange")
    m.style.paddingBottom = "1rem"
  }

}


function warn_message(p, text){
  const icon_tag = p.querySelector("span")
  if(icon_tag){
    change_icon(p,"warning", "yellow")
  }
  const span=document.createElement("span")
  span.style.color="yellow"
  span.innerHTML="warning."
  p.appendChild(span)

  if(text){
    const m = add_message(text,"yellow")
    m.style.paddingBottom = "1rem"
  }

}




function add_message(text, color, icon ) {
  const p = document.createElement("p")
  p.className = "console"
  if(color){
    p.style.color=color
  }
  if(icon){
    const span=document.createElement("span")
    span.classList.add("material-symbols-outlined")
    span.style.verticalAlign="middle"
    span.style.fontSize="17px"
    span.style.marginRight="3px"
    span.innerHTML=icon
    p.appendChild(span)  
  }
  if(text){
  p.appendChild(document.createTextNode(text))
  }
  tag("script-message").appendChild(p);
  const the_tag=tag("lower-console") || p  
  the_tag.scrollIntoView(false)
  return p
}




function get_url(page_id, suffix) {
  const appendix = suffix || ""
  if (PRODUCTION_MODE) {
    return `${PAGE_URL.protocol}//${PAGE_URL.host}/2022/02/${page_id}${appendix}.html`
  } else {
    return `blog/posts/${page_id}${appendix}`
  }
}

function add_console_dot() { // used to show progress when loading oracle data
  const console_lines = document.querySelectorAll(".console")
  const last_line = console_lines[console_lines.length - 1]
  if (last_line.style.marginBottom === "2rem") { return }
  if(last_line.innerHTML.endsWith("..")) {
    last_line.appendChild(document.createTextNode("."))
  }
  setTimeout(add_console_dot, 2000);
}


function toggle_elements_of_class(checkbox, visibility, class_name) {
  if (checkbox.tagName = "input") {
    let visibility = "none"
    if (checkbox.checked) { visibility = "" }
    get_query_controls(checkbox).query_box.querySelectorAll("." + checkbox.parentNode.getAttribute("name")).forEach((elem) => {
      elem.style.display = visibility
    });
  } else {
    //in this case, checkbox is really the query box
    checkbok.querySelectorAll("." + class_name).forEach((elem) => {
      elem.style.display = visibility
    });

  }
}

function header_clicked(el, dictionary_block_id) {
  const query_editor = document.getElementById(dictionary_block_id).parentElement
  if (query_editor) {
    const sql_editor = query_editor.getElementsByTagName("textarea")[0]
    sql_editor.value = el.innerText
    sql_editor.parentElement.update(sql_editor.value)
    //log(sql_editor)
  } else {
    throw 'dictionary block unavaliable'
  }
}



function toggle_prior_password(eye_ball){
  // finds the input that immediately preceeds the eyeball icon and toggles it between text and password, 
  
  let elem=eye_ball
  while (elem.tagName.toLowerCase() !== 'input') {
    elem = elem.previousSibling
  }
  if(elem.type==="text"){
    elem.type="password"
    eye_ball.innerHTML="visibility"
    eye_ball.title="Show Password"
  }else{
    elem.type="text"
    eye_ball.innerHTML="visibility_off"
    eye_ball.title="Hide Password"
  }
}


function server_properties_to_book_storage(data, deployment_id){
  // takes a connect response from google apps script and writes to bookstorage

  let server_props = data
  if(server_props.bookStorage){
    // adjust for frelay structire
    server_props = data.bookStorage.property
  }

  for(const [key,value] of Object.entries(server_props)){
    //log(key, value.value)
    if(!BookStorage.exists(key)){BookStorage.addItem(key)}
    try{
      BookStorage[key](JSON.parse(value.value))
    }catch(e){
      ;console.log("server_properties_to_book_storage Error", e)
    }
  }
  
  // BookStorage.deploymentId(deployment_id)
  // BookStorage.gasToken(data.token)
  //fill_server_configuration()
}



/**
 * makes a request to a google app script entpoint
 * this could be built out to use a differnt end point for paying customers
 * so they can run the book in a browser without setting up a google sheet
 * or apps script deployment endpoint
 */
async function server_post(payload, raw_url) {
  //log("raw url", raw_url)

  if(BookStorage.loginType()==="gas" || raw_url){
    return await frelayServerPost(payload, raw_url)
  }else if(BookStorage.loginType()==="paid"){
    return await paylayServerPost(payload)
  }else{
    // no other bookstorage.logintype requires sending data to the backend.
    return {status: "success", msg: "did not make post to server."}
  }
}

async function frelayServerPost(payload, raw_url){
  let url = raw_url
  if (!url) {
    url = get_gas_endpoint()
    if (!url) {
      // the student's google apps script is not known
      return null
    }

  }

  payload.token = get_gas_token()
  log("frelay server_post payload", payload)
  
  let reply
  try{
    reply = await fetch(url, {
      method: `POST`,
      body: JSON.stringify(payload),
    })
  }catch(e){
    //log("reply error",e.message)
    return {status:"error",message:e.message}
  }

  const text = await reply.text()
  try {
    return JSON.parse(text)
  } catch (e) {
    return {response: text}
  }

}

async function paylayServerPost(payload){
  log("calling paylay's server post")
  const client = await PaylayClient.init()
  return await client.server_post(payload)
}


function popstate(event) {
  //log(`popstate`,event)
  load_page(event.state, true)
}









function camelCaseToProperCase(text) {
  const result = text.replace(/([A-Z])/g, " $1");
  return result.charAt(0).toUpperCase() + result.slice(1);
}



async function submit_backend_package(payload, submit_through_backend=false){
  // sends information to a google form, needs to be gereralized for paid backend
  const url = `https://docs.google.com/forms/u/0/d/e/${get_from_book_storage("submissionInfo").formId}/formResponse`
  const body = build_google_form_payload(payload)
  
  // if we are configured for paylay or frelay, submit with that channel.  If it fails, try a direct submission
  if(submit_through_backend && (BookStorage.loginType()==="paid" || BookStorage.loginType()==="gas")){
    // route through paylay
    const payload={body:body, mode:"form-relay", url:url}
    const response = await server_post(payload)
    if(response.ok && response.text.includes("Your response has been recorded.")){
      return {status:"recorded"}
    }
  }

  // there is no backend configured to handle a redirect to google form, or the request failed.dispatch directly from the front end.  
  // in this case, There is no way to confirm receipt of the form data 
  const reply = await fetch(url, {
    method: `POST`,
    mode: 'no-cors',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'//;charset=UTF-8'
    },
    body: body
  })
  return {status:"submitted"}  //we cannot know if it was received, all we can say is that the request was dispatched
}


function build_google_form_payload(payload_object){
  //takes an object and returns the body necessary to submit to the form processor
  //const field_ids=[333028646,1323973366,275531788,1122039756,344552657,827802822,904289242,2102328485,1822900509,1808139614]
  const field_ids=get_from_book_storage("submissionInfo").fieldIds
  // split base 64 data into 50k blocks
  const payload = btoa(JSON.stringify(payload_object)).match(/.{1,50000}/g) ?? [];
  
  for(let x=0; x<payload.length; x++){
    const segment = payload[x]
    payload[x] = "entry." + get_from_book_storage("submissionInfo").fieldIds[x] + "=" + encodeURIComponent(segment)
  }
  // there are 10 fields for submitting data (indicies 0-9)
  // #10: student ID
  // #11: system ID
  // #12: submission type
  // #13: note, like for hte assesment name
  
  payload[10] =  "entry." + get_from_book_storage("submissionInfo").fieldIds[10] + "=" + encodeURIComponent(get_from_book_storage("submissionInfo").id)
  payload[11] =  "entry." + get_from_book_storage("submissionInfo").fieldIds[11] + "=" + encodeURIComponent(get_from_book_storage("systemId"))
  payload[12] =  "entry." + get_from_book_storage("submissionInfo").fieldIds[12] + "=" + encodeURIComponent(payload_object.submissionType)
  if(payload_object.assessmentName){
  payload[13] =  "entry." + get_from_book_storage("submissionInfo").fieldIds[13] + "=" + encodeURIComponent(payload_object.assessmentName)
  }
  return payload.join("&")
}

function pick_one(choices){
  //returns a random entry from an array
  return choices[Math.floor(Math.random() * choices.length)]
}

function button_waiting(button, text, icon = "hourglass_empty") {
  const old_value = button.innerHTML
  button.innerHTML = `${text} <span class="material-symbols-outlined blink" style="vertical-align:middle">${icon}</span>`
  return old_value
}


function string_to_token(data){
  // accepts an arbitrary string and returns a string that is a valid variable name, replacing all special characers with the underscore
  const data_array = data.split("")
  for(let x=0;x<data_array.length;x++){
    if((data_array[x].charCodeAt(0)>47 && data_array[x].charCodeAt(0)<58) || data_array[x].toUpperCase() !== data_array[x].toLowerCase()){
	   data_array[x]=data_array[x].toLowerCase()		
    }else{
      data_array[x]="_"
    }
  } 
  if(data_array[0].charCodeAt(0)>47 && data_array[0].charCodeAt(0)<58){
    data_array.unshift("_")
  }
  return data_array.join("")
}

// function get_user_data_object() {
//   //builds an a user data object from bookstorage


//   return {
//     student_id:BookStorage.studentId(),
//     first_name:BookStorage.studentFirstName(),
//     last_name:BookStorage.studentLastName(),
//     email:BookStorage.studentEmail(),
//     class_key:BookStorage.courseCode(),
//   }
// }

function object_data(object) {
  // returns the number of top-level keys in an object and the number of those which are defined
  const data = {
    count: 0,
    defined: 0
  }
  for (const value of Object.values(object)) {
    data.count++
    if (value !== undefined && value.trim() !== '') {
      data.defined++
    }
  }
  return data
}





function get_from_book_storage(attribute, alternate=""){
  //gets a value from book storage or it's alternate
  try{
    return BookStorage[attribute]()
  }catch(e){
    return alternate
  }
}

function toggle_next_row(clicked_elem) {
  // toggles the visibility of next row of a table.  used for showing field help in a form
  let elem = clicked_elem
  while (elem.tagName !== 'TR') {
    elem = elem.parentNode
  }
  elem = elem.nextElementSibling
  if (elem.style.display === "none") {
    elem.style.display = ""
  } else {
    elem.style.display = "none"
  }
}


function getCoords(elem) {
  // get coords of elem WRT document
  let box = elem.getBoundingClientRect();
  return {
    top: box.top + window.pageYOffset,
    right: box.right + window.pageXOffset,
    bottom: box.bottom + window.pageYOffset,
    left: box.left + window.pageXOffset
  };
}



function set_prior_next_link(page_id) {
  // set up all four navigation buttons
  // page_id is the current page being displayed
  
  let next_id
  let prior_id
  if(post_list[page_id] && post_list[page_id].hidden){
    // this is a hidden page, supress TOC, forward, next
    //log(post_list[page_id])
    //tag("toc").style.display="none"
    //tag("prior-next").style.display="none"
  }else{
    //tag("toc").style.display=""
    //tag("prior-next").style.display=""
    // this is a regular page, show it all
    // if (page_id.match(/contents(-[\d]+)+/)) {
    //   //this is a section contents menu
    //   const menu_path=page_id.split("-")
    //   menu_path.shift()
    //   log("menu", menu,"contents-" + menu_path.join("-"), "==================================================")
    //   next_id = sequence[page_id]?.next
    //   prior_id = sequence[page_id]?.prior
    // } else {
    //   // this is a regular page
    //   next_id = sequence[page_id]?.next
    //   prior_id = sequence[page_id]?.prior
    // }
    next_id = sequence[page_id]?.next
    prior_id = sequence[page_id]?.prior

    log("==========next_id",next_id,"prior_id",prior_id)
    // build the forward / next buttons
    if (next_id) {
      document.getElementById(`next-page`).innerHTML = `<span class='page-link' data-nav_id="${page_id}" data-move="next" onclick="navigate(event)"><span id='navigate-next-label'></span><span class='material-symbols-outlined button inline-icon'>arrow_forward</span></span>`
      //log("setting next button event")
      const button = tag("next-button")
      button.addEventListener("click", navigate, false);
      button.dataset.nav_id = page_id
      button.dataset.move = "next"
      tag("next-button").style.visibility="visible"
    } else {
      tag("next-page").innerHTML = ""
      tag("next-button").style.visibility="hidden"
    }

    
    if (prior_id && prior_id!=="contents-0") {
      document.getElementById(`go-back-div`).innerHTML = `<span class='page-link' data-nav_id="${page_id}" data-move="prior" onclick="navigate(event)"><span class='material-symbols-outlined button inline-icon'>arrow_back</span><span id='navigate-prior-label'></span></span>`
      const button = tag("prior-button")
      button.addEventListener("click", navigate, false);
      button.dataset.nav_id = page_id
      button.dataset.move = "prior"
      tag("prior-button").style.visibility="visible"
    } else {
      tag("go-back-div").innerHTML = ""
      tag("prior-button").style.visibility="hidden"
    }
  }

}

function navigate(event) {
  //debugger
  // make sure we scoll up to the top of the page, since the user is going to look at a new page
  window. scrollTo(0,0)
  //navigate to the next page based on the current page
  //log("navigate===========",JSON.stringify(event.target.dataset))
  let target=event.target
  while(!target.dataset.move){
    target=target.parentNode
  }
  
  const new_page_id = get_prior_next_page(target.dataset.nav_id,target.dataset.move).id
  if(new_page_id===BookStorage.currentPage()){
    if(target.dataset.move==="next"){
      message({
        message:"You have reached the end of the content.",
        title:"Nowhere to go",
        seconds:4,
        show:true
      })
    }else{
      message({
        message:"You have reached the beginning of the content.",
        title:"Nowhere to go",
        seconds:4,
        show:true
      })  
    }
  }else{
    load_page(new_page_id)
  }
  
}

function get_prior_next_page(page_id, prior_next){
  // takes a page_id and returns the prior or next based on the current conditional 
  //log("get_prior_next_page",page_id, prior_next)
  const current_db = BookStorage.dbType()
  let new_page_id=page_id || "introduction"
  let x = 0
  //debugger
  while(true){
    if(x++>1000){return {}}
    if(sequence[new_page_id]===undefined){return{}}

    new_page_id = sequence[new_page_id][prior_next]
    if(!new_page_id){
      // reached the end
      return {}
    }else if(sequence[new_page_id].conditional){
      // the page is conditional, check if it should be shown
      //log("conditional",sequence[new_page_id].conditional)
      if(sequence[new_page_id].conditional.includes(current_db)){
        return {id:new_page_id,label:sequence[new_page_id].label}
      }
    }else{
      // the page is unconditional, show it
      //log("new page id",new_page_id)
      return {id:new_page_id,label:sequence[new_page_id].label}
    }
  }
}

function show_panel(label) {
  if(menu_list[label].hidden){
    tag("toc").style.display="none"
    tag("prior-next").style.display="none"
  }else{
    tag("toc").style.display=""
    tag("prior-next").style.display=""
  }

  const id = label_to_id(label)
  // show the panel
  for (const elem of document.querySelectorAll(".content-panel")) {
    elem.style.display = "none"
  }
  // highlight the the menu
  for (let i = 0; i < menu.length; i++) {
    if(tag(`menu-${i}`)){
      tag(`menu-${i}`).classList.remove("active")
    }
  }
  if(tag(`menu-${tag(id).dataset.menuNumber}`)){
    tag(`menu-${tag(id).dataset.menuNumber}`).classList.add("active")
  }

  tag(id).style.display = "block"
  return tag(id)
}

async function load_page(page_id, replace = false) {
  //log("page_id", page_id)
  //log("sequence", sequence)
  //log("section_map", section_map)
  //log("label_map", label_map)
  hide_toc()
  if (!page_id || page_id === "contents-0") {
    page_id = "introduction"
  }

  
  set_current_page(page_id)


  if (!replace) {
    history.pushState(page_id, ``, `/?${page_id}`)
  }

  
  set_prior_next_link(page_id)

  //log("at load page", page_id)
  //highlight_menu(section_map[page_id])
  //log("pageid", page_id)
  const panel = show_panel(section_map[page_id])
  panel.dataset.pageId = page_id

  // check to see if we are showing a section contents page
  log("about to check to see if we are on a section contents=========================")
  if (page_id.match(/contents(-[\d]+)+/)) {
    log("we are on a section content page")
    //const page_body=document.getElementById(`page-body`)

    const menu_path=page_id.split("-")
    menu_path.shift()
    panel.innerHTML = document.getElementById("contents_" + menu_path.join("-")).outerHTML
    // log(`contents_" + menu_path.join("-")`, "contents_" + menu_path.join("-"))
    // log("panel contents", panel.innerHTML)
    configure_book()
    return
  }


  // //log("page_id", page_id)
  // //log("sequence", sequence)
  // //log("label_map", label_map)

  if (post_list[page_id]?.type === "assessment") {
    // this is an assessment, treat it totally differently from regular posts
    load_assessment(page_id)
    configure_book()
    return
  }else if (post_list[page_id]?.type === "javascript") {
    // This page is loaded by running JS
    
    window[page_id](page_id);

    configure_book()
    return
  }


  //log(`page_id`,page_id)

  //separate js from html in post body
  const begin_script_tag = String.fromCharCode(60, 115, 99, 114, 105, 112, 116, 62)
  const end_script_tag = String.fromCharCode(60, 47, 115, 99, 114, 105, 112, 116, 62)
  const post_javascript = []
  const post_html = []
  //log(get_url(page_id),page_id, post_list)
  //log("post_list[page_id].format",post_list[page_id].format)

  let post_content
  // check to see if we are showing a section contents page
  //log("checking for a section contents page", page_id)
  if (page_id.match(/contents(-[\d]+)+/)) {
    const menu_path=page_id.split("-")
    menu_path.shift()
    log("loading a section contents page","contents_" + menu_path.join("-"))
    //debugger
    //const page_body=document.getElementById(`page-body`)
    //if (panel.innerHTML.length === 0) {
      post_content = document.getElementById("contents_" + menu_path.join("-")).outerHTML
    //} else {
    //  configure_book()
    //  return
    //}
  } else {
    post_content = await get_post_content(get_url(page_id), post_list[page_id].format)
    //log("post_content",post_content)
  }

  const post_array = post_content.split(end_script_tag)

  for (const block of post_array) {
    if (block.includes(begin_script_tag)) {
      //this block has a script
      const segment = block.split(begin_script_tag)
      if (segment.length === 1) {
        // no html here
        post_javascript.push(segment[0])
      } else {
        // this segment has both HTML and JS
        post_html.push(segment[0])
        post_javascript.push(segment[1])

      }
    } else {
      // this block does not have a script
      post_html.push(block)
    }
  }

  //log("HTML", post_html)

  // render the html of the post 
  //document.getElementById(`page-body`).innerHTML=post_html.join(``)
  log("post_html", post_html)
  if(sequence[page_id]?.number){

  }
  panel.innerHTML = post_html.join(``)

  // only display the tags that should be shown based on how the book is configured
  configure_book()
  
  // run the JS of the post
  if (post_javascript.length > 0) {
    const newScript = document.createElement(`script`)
    newScript.innerHTML = post_javascript.join(``)
    document.getElementsByTagName(`head`)[0].appendChild(newScript)
  }


  // if(get_cookie(`deployment_id`)){
  // we are configured to run oracle queries, highlihgt the query block
  codeInput.registerTemplate('code-input', codeInput.templates.prism(Prism, [new codeInput.plugins.Indent()]));
  // disable query editing if we are in book mode
  //log("get_book_db_type()", get_book_db_type())
  if (get_book_db_type() === 'book') {
    for (const textarea of document.querySelectorAll(".editor")) {
      textarea.style.display = "none"
    }
  }
  // }else{
  //   // we are not configured to run real queries, highlight the simulated ones
  //   Prism.highlightAll()
  // }
  get_diagrams()



}
function strip_trailing_div(content) {
  //log(`at strip trailing div.  Content:`,content, content.length)
  // if (!content.includes(`<div`)) { return content }
  // const post = content.split(`\n`)
  // while (!post.pop().includes(`<div`)) { }
  // return post.join(`\n`)

return content.split('<div style="clear:both;"></div>').join('').split('<div style="clear:both; padding-bottom:0.25em"></div>').join('')

}

async function get_post_json(url) {
  // from the post, we get a div at the end of our post 
  const post = await get_post_content(url,'json')

  log("-------------------",url,"---------------------")
  log(post)
  return post
  //return JSON.parse(post)
}


async function get_post_content(url, format) {
  let page_id = url.split("/")
  page_id=page_id[page_id.length-1].split(".")[0]
  millis=new Date().getTime()
  const response = await fetch(url + "?t=" + millis)
  let post_body = await response.text();
  //log ("post_body",post_body)

  if (PRODUCTION_MODE) {// in production, the JS in base 64 encoded
    const parser = new DOMParser();
    const doc = parser.parseFromString(post_body, `text/html`);
    post_body = strip_trailing_div(doc.querySelector(`.post-body`).innerHTML)
  }
  

  //log("format",format)
  if (format === `markdown`) {
    //pre-process for any query statements
    let body = decodeHtml(post_body)



    //pre-process REFERENCE links

    if(Array.isArray(body)===true){
      body = body.join("").split('---[REF]---')
    }else{
      body = body.split('---[REF]---')
    }
    //body = body.join("").split('---[REF]---')
    if (body.length === 1) {
      body=body[0]
    }else{
      // we had at least one REFERENCE
      for (let x = 0; x < body.length - 1; x = x + 2) {
        log(body[x+1])
        const ref=JSON.parse("{" + body[x+1] +"}")
        if(ref.style==="heading"){
          body[x+1] = `# ${sequence[page_id].number?sequence[page_id].number+". ":""}${sequence[page_id].label}`
        }else if(ref.style==="link"){
          const label=ref.label || "Lesson"
          body[x+1] = `<a href='${window.location.origin+"?"+ref.pageId}'>${sequence[ref.pageId].number?label +" " +sequence[ref.pageId].number+" ("+sequence[ref.pageId].label+")":"the " + label.toLowerCase() + " on " + sequence[ref.pageId].label}</a>`
        }
        
      }
    }




    // pre-process queries
    if(Array.isArray(body)===true){
      body = body.join("").split('---[SQL]---')
    }else{
      body = body.split('---[SQL]---')
    }
    //log("body",body)
    if (body.length === 1) {
      body=body[0]
    }else{
      // we had at least one query
      for (let x = 0; x < body.length - 2; x = x + 3) {
        let query_params = body[x + 1].trim().split("\n")
        for (let i = 0; i < query_params.length; i++) {
          const param = query_params[i].split(":")
          param[0] = '"' + param[0].trim() + '"'
          param[1] = '"' + param[1].trim() + '"'
          query_params[i] = param.join(":")
        }
        query_params = JSON.parse("{" + query_params.join(",") + "}")
        const sql = body[x + 2].trim().split("\n\n").join("\n<line break in a QuErY>")
        let query_block = await get_query_block({
          sql: sql,
          connection : query_params.connection,
          schema : query_params.schema,
          owner : query_params.owner,
          filename : query_params.result,
          diagram_settings : query_params.diagram,
          query_box_height : query_params.height
          })
        body[x + 1] = "\n" + query_block
        body[x + 2] = "\n"
      }
    }

    //pre-process AI blocks
    if(Array.isArray(body)===true){
      body = body.join("").split('---[AI]---')
    }else{
      body = body.split('---[AI]---')
    }
    //body = body.join("").split('---[AI]---')
    if (body.length === 1) {
      body=body[0]
    }else{
      // we had at least one AI block
      for (let x = 0; x < body.length - 1; x = x + 2) {
        const ai_blocks=[]
        const ai_source = JSON.parse(body[x+1])
        for(const ai_exchange of ai_source){
          ai_blocks.push(get_ai_block(ai_exchange))
        }
        body[x+1] = ai_blocks.join("")
        
      }
    }


    //pre-process sidebars

    if(Array.isArray(body)===true){
      body = body.join("").split('---[SIDEBAR]---')
    }else{
      body = body.split('---[SIDEBAR]---')
    }
    //body = body.join("").split('---[SIDEBAR]---')
    if (body.length === 1) {
      body=body[0]
    }else{
      // we had at least one sidebar
      for (let x = 0; x < body.length - 1; x = x + 2) {
        const sidebar=JSON.parse("{" + body[x+1] +"}")
        body[x+1] = `<div class="sidebar">
        <div class="sidebar title ${sidebar.type}"><table><tr><td style="width:100%">${sidebar.title}</td><td style="text-align: right;">${sidebar.type.charAt(0).toUpperCase()
          + sidebar.type.slice(1)}</td></tr></table></div>
        <div class="sidebar body">${sidebar.text}</div></div>
    `
        
      }
    }





    //pre-process evaluate blocks

    if(Array.isArray(body)===true){
      body = body.join("").split('---[EVALUATE]---')
    }else{
      body = body.split('---[EVALUATE]---')
    }
    //body = body.join("").split('---[EVALUATE]---')
    if (body.length === 1) {
      body=body[0]
    }else{
      // we had at least one evaluation block
      let prior_eval_block={type:"none"}
      for (let x = 0; x < body.length - 1; x = x + 2) {
       
        const eval_block=JSON.parse("{" + body[x+1] +"}")

        // pull in missing data in an eval from the prior plan
        if(eval_block.type==="evaluate"){
          if(eval_block.task===undefined){ eval_block.task=prior_eval_block.task}
          if(eval_block.columns===undefined){ eval_block.columns=prior_eval_block.columns}
          if(eval_block.tables===undefined){ eval_block.tables=prior_eval_block.tables}
          if(eval_block.rows===undefined){ eval_block.rows=prior_eval_block.rows}
          if(eval_block.order===undefined){ eval_block.order=prior_eval_block.order}
          if(eval_block.query===undefined && prior_eval_block.query!==undefined){ eval_block.query=prior_eval_block.query}
        }else if(eval_block.type==="plan"){
          if(eval_block.columns===undefined){ eval_block.columns="All"}
          if(eval_block.order===undefined){ eval_block.order="Not specified"}
          if(eval_block.rows===undefined){ eval_block.rows="All"}
        }



        //set the evaluation sidebar type
        let eval_type = "Plan to retrieve data"
        if(eval_block.type==="evaluate") {eval_type = "Examine the proposed query"}

        //create feedback icons for examine blocks
        const eval_correct_icon = "<span class='material-symbols-outlined inline-icon green'>check_circle</span>"

        const eval_incorrect_icon = "<span class='material-symbols-outlined inline-icon red'>cancel</span>"

        //initialize feedback variables
        let column_issues_display = ''
        let table_issues_display = ''
        let row_issues_display = ''
        let order_issues_display = ''

        //if examine block populate feedback
        if(eval_block.type==='evaluate'){
          
          //feedback is clean by default
          column_issues_display = ` ${eval_correct_icon}`
          table_issues_display = ` ${eval_correct_icon}`
          row_issues_display = ` ${eval_correct_icon}`
          order_issues_display = ` ${eval_correct_icon}`

          if(eval_block.column_issues){//column issues identified
            column_issues_display = ` ${eval_incorrect_icon} <span class='red'>${eval_block.column_issues}</span>`
          }

          if(eval_block.table_issues){//table issues identified
            table_issues_display = ` ${eval_incorrect_icon} <span class='red'>${eval_block.table_issues}</span>`
          }

          if(eval_block.row_issues){//row issues identified
            row_issues_display = ` ${eval_incorrect_icon} <span class='red'>${eval_block.row_issues}</span>`
          }

          if(eval_block.order_issues){//order issues identified
            order_issues_display = ` ${eval_incorrect_icon} <span class='red'>${eval_block.order_issues}</span>`
          }          
        }

        prior_eval_block=eval_block

        //build the evaluation sidebar body
        const eval_block_text = []
        eval_block_text.push(`<b>Task:</b> ${eval_block.task}`)
        if(eval_block.query){eval_block_text.push(`<hr><b>Proposed query:</b><br>${eval_block.query}`)}
        if(eval_block.type==="plan"){
          eval_block_text.push(`<hr><b>Make the plan:</b>`) 
        }else{
          eval_block_text.push(`<hr><b>Evaluate the query:</b>`)
        }
        eval_block_text.push('<ol class="plan-list"><li>Which columns should be shown?<br>')
        if(eval_block.columns) {eval_block_text.push(`<span class='plan'>${eval_block.columns}</span>`+column_issues_display)}
        eval_block_text.push("</li><li>What tables hold the data?<br>")
        if(eval_block.columns) {eval_block_text.push(`<span class='plan'>${eval_block.tables}</span>`+table_issues_display)}
        eval_block_text.push("</li><li>Which rows should be included?<br>")
        if(eval_block.columns) { eval_block_text.push(`<span class='plan'>${eval_block.rows}</span>`+row_issues_display)}
        eval_block_text.push("</li><li>What order should rows be in?<br>")
        if(eval_block.columns) {eval_block_text.push(`<span class='plan'>${eval_block.order}</span>`+order_issues_display)}
        eval_block_text.push("</li></ol>")

        body[x+1] = `<div class="sidebar">
        <div class="sidebar title evaluate"><table><tr><td style="width:100%">${eval_type}</td><td style="text-align: right;">${proper_case(eval_block.type)}</td></tr></table></div>
        <div class="sidebar body">${eval_block_text.join('')}</div></div>
    `
        
      }
    }


    //pre-process figures

    if(Array.isArray(body)===true){
      body = body.join("").split('---[FIGURE]---')
    }else{
      body = body.split('---[FIGURE]---')
    }
    // body = body.join("").split('---[FIGURE]---')
    if (body.length === 1) {
      body=body[0]
    }else{
        // we had at least one image
      let figure_number=1
      const figures=[]
      for (let x = 0; x < body.length - 1; x = x + 2) {
        log(body[x+1])
        const figure=JSON.parse("{" + body[x+1] +"}")

        let image_scroll = ''
        let image_scale = ''

        if(figure.imgHandling){
          if(figure.imgHandling==='scale'){
            image_scale = 'class="img-scale "'
          }else if(figure.imgHandling==='scroll'){
            image_scroll = ' img-scroll"'
          }
        }

        body[x+1] = `<div class="figure-container"><div class="figure">
        <div class="figure body${image_scroll}"><img ${image_scale}src="${figure.url}" title="${figure.altText}"></div>
        <div class="figure title">Figure ${figure_number}:&nbsp; ${figure.title}</div>
    </div></div>`
        figures.push(figure.id)  
        figure_number++
      }
      body=body.join("")
      // now replace the figure numbers
      for(let x=0;x<figures.length;x++){
        body=body.split(`---[${figures[x]}]---`).join(`Figure ${x+1}`)
      } 
    }


    const ai_name_regex = /\^ai_name\^/g;
    const db_name_regex = /\^db_name\^/g;
    return marked.parse(body)
      .split("<line break in a QuErY>")
      .join("\n")
      .replace(ai_name_regex, '<span class="conditional gpt">ChatGPT</span><span class="conditional bard">Bard</span><span class="conditional bing">Bing Chat</span>')
      .replace(db_name_regex, '<span class="conditional sqlite">SQLite</span><span class="conditional oracle">Oracle</span><span class="conditional dataworld">data.world</span>')

  } else if (format === `json`) {
    try{
      return JSON.parse(post_body)
    }catch(e){
      // json.parse could fail if the json has been fake-encrypted, try to reverse bytes
      return JSON.parse(b64DecodeUnicode(post_body.split('').reverse().join('')))
    }
  } else {
    if(PRODUCTION_MODE){
      return decodeHtml(post_body)
    }else{
      return post_body
    }
    
  }

}

function b64DecodeUnicode(str) { //https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings
  // Going backwards: from bytestream, to percent-encoding, to original string.
  return decodeURIComponent(atob(str).split('').map(function(c) {
      return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
  }).join(''));
}

function htmlDecode(input) {
  var doc = new DOMParser().parseFromString(input, "text/html");
  return doc.documentElement.textContent;
}


function get_ai_block(ai){
  let post_block = ai.posttext
  let pre_block = ai.pretext  
  // height
  let height = ai.responseHeight
  if (!height) { height = ai.response.split("\n").length }
  if (height < 3) {
    height = 3
  } else if (height > 30) {
    height = 30
  }


  let response_block = ai.response
  if(response_block){
    response_block=`<code-input lang="sql" class="rows-${height}" value="${response_block}" style="margin: 1rem 0; "></code-input>`
  }else{
    response_block=""
  }

  return `<div style="width:90%;background-color:#CFD4D2;color:#384440;margin:auto;padding:1rem 0;margin-top:1rem;margin-bottom:1rem;border-radius:5px">
  <div style="width:90%;margin:auto; border: 2px solid #6F7975;border-radius: 10px;background-color:#EFF1F0;margin-bottom:1rem;padding:.2rem .5rem;filter: drop-shadow(4px 4px 4px #7D7F7E);"><table><tr><td style="width:100%">${ai.prompt}</td><td style="vertical-align:bottom;"><span class="material-symbols-outlined" style="vertical-align: middle">send</span></td></tr></table></div>
  <div style="width:95%;margin:auto;">${pre_block}
  ${response_block}
  ${post_block}
  </div></div>
`


}

function get_attribute(tag, attribute_name, delimiter = '"') {
  //accepts a tag and an attribute name and retrens the attriute's value
  const splitted = tag.split(attribute_name)
  if (splitted.length === 1) { return null }
  return splitted[1].split(delimiter)[1].split(delimiter)[0]
}


function build_section_map(section_map, menu, level = 0, toc, top_level_menu, menu_path=[], parent_is_hidden=false) {
  //section map is an object to map name of pages to thier sections so se can highlight a section when a page is direct-loaded  
  let menu_number = 0
  log("NEXT_LESSON_NUMBER",NEXT_LESSON_NUMBER)

  //log("menu in build section map", menu)
  const menu_condition_list=[]
  for (let m=0;m<menu.length;m++) {
    // build conditional display classnames
    const entry = menu[m]
    let conditional_display_classes = ""
    let condition_list=["ALL"]
    if (entry.conditional) {
      conditional_display_classes = "conditional " + entry.conditional
      condition_list = entry.conditional.split(" ")
    }

    // add the conditions to the menu's conditions
    for(const condition of condition_list){
      if(!menu_condition_list.includes(condition)){
        menu_condition_list.push(condition)
      }
    }
    if (entry.page) {
      section_map[entry.page] = top_level_menu
      const sequence_object={label:entry.label,id:entry.page}

      if(entry.number!==undefined){
        log("entry.number===",entry.number,entry.number==="auto")
        if(entry.number==="auto"){
          sequence_object.number=NEXT_LESSON_NUMBER
        }else{
          sequence_object.number=entry.number
        }
        NEXT_LESSON_NUMBER=sequence_object.number + 1
        
      }

      if (entry.conditional){
        sequence_object["conditional"]=entry.conditional
      }

      if(!entry.hidden && !parent_is_hidden){
        sequence_array.push(sequence_object)
        toc.push(`<div class="page-link ${conditional_display_classes}" onclick="load_page('${entry.page}');hide_toc()" id="${entry.page}" style="padding-left:${level}rem">${sequence_object.number?sequence_object.number + ". ":""}${entry.label}</div>`)
      }  
      //label_map[entry.page] = entry.label
      post_list[entry.page] = entry

    } else if (entry.menu) {
      //used to build menu ids
      if(level>menu_path.length-1){
        menu_path.push(menu_number)
      }else if(level<menu_path.length-1){
        menu_path.pop()
        menu_path[level]=menu_path[level]+1
        toc.push("</div><!==menu end 1==>")
      }else{
        menu_path[level]=menu_number
        toc.push("</div><!==menu end 2==>")
      }

      log("level",level, entry.label, menu_path)
      if (level === 0) { 
        top_level_menu = entry.label 
      }

      //if(level===1){debugger}

      section_map["contents-" + menu_path.join("-")] = top_level_menu
      //label_map["contents-" + menu_number] = entry.label + " Contents"
      const sequence_object={label:entry.label + " Contents", id:"contents-" + menu_path.join("-")}

      //log("menu", entry.label, level)
      if(!entry.hidden && !parent_is_hidden){
        sequence_array.push(sequence_object)
        menu_number++        
        toc.push(`<!==menu begin==><div id="contents_${menu_path.join("-")}">`)
        const font_size=1.5-(.2*level)
        toc.push(`<div CONDITIONAL_CLAUSE style="margin-left:${level}rem;font-size:${font_size}rem;font-weight:bold;border-bottom:2px solid black">${entry.label}</div>`)
      }
      menu_list[entry.label] = entry
      //log("about to recurse, NEXT_LESSON_NUMBER",NEXT_LESSON_NUMBER)
      const mc_list = build_section_map(section_map, entry.menu, level + 1, toc, top_level_menu, menu_path, entry.hidden || parent_is_hidden)
      if(mc_list.length>0 && !mc_list.includes("ALL")){
        // if any of the sub entires of this menu had conditionals, put them on the menu
        menu[m].conditional=mc_list.join(" ")
        sequence_object["conditional"]=menu[m].conditional
        for(let x=toc.length-1;x>-1;x--){
          //log("x",x)
          if(toc[x].includes("CONDITIONAL_CLAUSE")){
            toc[x]=toc[x].replace("CONDITIONAL_CLAUSE",`class="conditional ${menu[m].conditional}"`)
            break
          }
        }
      }else{
        //clear conditional cluase entry
        for(let x=toc.length-1;x>-1;x--){
          if(toc[x].includes("CONDITIONAL_CLAUSE")){
            toc[x]=toc[x].replace(" CONDITIONAL_CLAUSE "," ")
            break
          }
        }
      }
      if(!entry.hidden && !parent_is_hidden){
        //log("last toc entry", toc)
      }
    }
  }
  return menu_condition_list
}


async function load_css_from_blog_post(url) {
  // gets css that is stored in a post and load it
  const css = document.createElement(`style`)
  css.innerHTML = await get_post_content(url)
  document.getElementsByTagName(`head`)[0].appendChild(css)
}


/** 
 * gets js that is stored as a base-64 encoded stirng (if fethed in production) 
 * in a post and loads it to the <header> tag.
 * If the tag already exsists, then it will override the js tag with the content of the file. 
 * @param {string} file_name the name of the file we want to get. It gets converted into 
 * a URL.
 */
async function load_js_from_blog_post(file_name, script_type) {
  const url = get_url(file_name)

  let source = await get_post_content(url)
  if (PRODUCTION_MODE) { source = atob(source) }

  let js = document.getElementById(file_name)


  if (!js) {
    js = document.createElement(`script`)
    js.setAttribute("id", file_name)
    if(script_type){
      js.setAttribute("type", script_type)
    }else{
      const type_attr = source.match(/@type=["'](.*)['"]@/)
      if (type_attr) {
        js.setAttribute("type", type_attr[1])
      }
    }
    js.async = false;
    document.getElementsByTagName(`head`)[0].appendChild(js)
  }
  js.addEventListener('load', function() {
    //log("hi hi hi");
  });

  js.replaceChildren(source)

}

async function add_to_head(tag_name, attributes) {
  // place a script tag that imports a script from another location
  let js = document.getElementById(attributes.id)
  if (!js) {
    js = document.createElement(tag_name)
    for(const [attr_name, attr_val] of Object.entries(attributes)){
      js.setAttribute(attr_name, attr_val)
    }
    document.getElementsByTagName(`head`)[0].appendChild(js)
  }
}


function get_params(query_string) {
  if (!query_string) {
    query_string = PAGE_URL.search
  }
  const url_params_array = query_string.split("?").join("").split("&")
  const url_params = {}

  for (let x = 0; x < url_params_array.length; x++) {
    // returns the params from the url as an object
    const temp = url_params_array[x].split("=")
    url_params[decodeURI(temp[0])] = decodeURI(temp[1])
  }
  return url_params
}

async function start_me_up() {//==================================================================
  // add scripts imports to head

  add_to_head("link",{
    id:"google-fonts",
    href:'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200',
    rel:'stylesheet'
  })

  add_to_head("script",{
    id:"prism-1",
    src:'https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/components/prism-core.min.js'
  })

  add_to_head("script",{
    id:"prism-2",
    src:"https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/plugins/autoloader/prism-autoloader.min.js"
  })

  add_to_head("script",{
    id:"sqlite",
    crossorigin:'anonymous',
    integrity:'sha512-n7swEtVCvXpQ7KxgpPyp0+DQQEf5vPpmzCRl14x2sp2v5LpCYCjrAx03mkBAbWwGF9eUoIk8YVcDFuJRIeYttg==',
    referrerpolicy:'no-referrer',
    src:'https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/sql-wasm.js'
  })

  add_to_head("script",{
    id:'markdown',
    crossorigin:'anonymous',
    integrity:'sha512-uwSxMaa/W7dmSIXEd07BMVymisMRRUS/Pr5a76AquekKKu9HWn4rBiCd+ZtwqnoijAJvttdrz8krzP26kZjg0Q==',
    referrerpolicy:'no-referrer',
    src:'https://cdnjs.cloudflare.com/ajax/libs/marked/4.2.12/marked.min.js'
  })

  add_to_head("script",{
    id:"sjcl",
    crossorigin:'anonymous',
    integrity:'sha512-s0r9TyYSs5CusSDL5s/QEZQZ4DNYLDXx0S+imS+SHR9mw0Yd0Z5KNS9dw7levSp7GpjOZu/bndds3FEDrKd8dg==',
    referrerpolicy:'no-referrer',
    src:'https://cdnjs.cloudflare.com/ajax/libs/sjcl/1.0.8/sjcl.min.js'
  })

  load_js_from_blog_post("firebase-js","module")
  continue_me_up()
}

async function continue_me_up()  {
  // wait to be sure the start me up things have loaded

  if( typeof firebase==='undefined'      ||
      typeof Prism?.highlightAll==='undefined' ||
      typeof marked?.parse==='undefined' ||
      typeof sjcl?.encrypt==='undefined'
  ){
    log("caught")
    setTimeout(continue_me_up, 100)
    return

  }
  log("continuing")

  await load_js_from_blog_post("system-book-specific-js")

  try{ // loading stuff that is specific to this particular book (eg, sql stiff)
    book_specific_continue_me_up(1)
  }catch(e){
    log ("Error in book_specific_continue_me_up. step 1.  This book may not have one",e)
  }

  document.body.innerHTML = `<div id="message-center"></div>        <div id='page-container' style='background-color:white; max-width:1024px;margin:auto;padding-bottom: 1rem'><div class='post-body entry-content' id='post-body'></div><table cellpadding='0' cellspacing='0' style='border-collapse: collapse'><tr><td style='width:100%'><div class='topnav' id='menu'></div></td><td style='vertical-align:bottom; background-color:#888;color:whitesmoke;padding:0 5px'> <span class='material-symbols-outlined button' id='user-login-icon' onclick='show_user_menu(event)' style='font-size:30px'>person</span></td></tr></table><div id='toc' style='margin: 0;'><table style='border-collapse:collapse'><tr><td style='background-color:lightgray;'><span style='display:block' class='material-symbols-outlined button' id='prior-button' title='Prior Page'>navigate_before</span></td><td id='top-info' onclick='toggle_code()' style='cursor:pointer;background-color:#eee;width:100%;text-align:center;color:#aaa'>Table of Contents</td><td style='background-color:#eee'><span class='material-symbols-outlined button' id='toc-button' onclick='toggle_code()' title='Show Table of Contents'>expand_more</span></td><td style='background-color:lightgrey;'><span style='display:block' class='material-symbols-outlined button' id='next-button' title='Next Page'>navigate_next</span></td></tr></table><div id='contents' style='display:none;background-color:lemonchiffon;padding:1rem'></div></div><div id='panels'><div class='content-panel' data-menu-number='0' id='page-body'><div style='text-align:center'><span id='loading-message'>Loading Page</span><span class='material-symbols-outlined blink' style='vertical-align:middle;'>hourglass_empty</span></div></div></div><div class='row' id='prior-next'><div class='column' id='go-back-div' style='margin: 1rem;'></div><div class='column' id='next-page' style='text-align:right;margin: 1rem;'></div></div></div>`
  addEventListener(`popstate`, popstate);

  // read the configuration from the cookie
  //load_config()
  

  await Promise.all([
    load_js_from_blog_post("code-input-js"),
    load_js_from_blog_post("ui-js"),
    load_js_from_blog_post("auto-storage-js"),
    load_js_from_blog_post("authenticate-js"),
  ])
  await Promise.all([
    load_js_from_blog_post("error-js"),
    load_js_from_blog_post("paylay-client-js"),
    load_js_from_blog_post("indent-js"),
    load_js_from_blog_post("secret-keeper-js"),
    load_css_from_blog_post(get_url("book-css")),
  ])

  await Promise.all(book_specific_continue_me_up(2))

  log("code loaded")
  let query_string = window.location.href.split(`?`)[1]
  if (!query_string) { query_string = get_from_book_storage("currentPage","introduction" ) }
  if (!query_string) { query_string = ""}
  if (!query_string.includes("=")) {
    query_string = "page=" + query_string
  }
  const url_params = get_params(query_string)

  // read bookStorage defautls from url_params
  // this allows any bookStorage  value to be set in the initial 
  for(const [key,val] of Object.entries(url_params)){
    //log(key, val)
    if(["bookContents","aiType"].includes(key)){  // list of url settable bookstorage functions
        BookStorage[key](val)
    }
  } 

    //log("BookStorage.aiType()",BookStorage.aiType())
  

  menu = await get_post_content(get_url(BookStorage.bookContents()), `json`)
  

  const toc = []
  build_section_map(section_map, menu, 0, toc)
  toc.push(toc.shift())
  //log("section_map",section_map)
  //log("toc",toc)
  //log(`menu_data`,menu)
  //log(`prost_format`,post_list)


  //log("BookStorage.loginType",BookStorage.loginType())
  //log("BookStorage_canary",BookStorage.canary())
  //log("BookStorage_token",BookStorage.token())
  //log("BookStorage.loggedIn",BookStorage.loggedIn())

  // build prior next info
  //debugger
  for (let x = 0; x < sequence_array.length; x++) {
    //log(x,sequence_array[x].id)
    //debugger
    if (sequence[sequence_array[x].id] === undefined) { sequence[sequence_array[x].id] = {} }

    sequence[sequence_array[x].id].label=sequence_array[x].label
    
    if(sequence_array[x].number){
      sequence[sequence_array[x].id].number = sequence_array[x].number
    }
    if(sequence_array[x].conditional){
      sequence[sequence_array[x].id].conditional = sequence_array[x].conditional
    }

    if (x > 0) { sequence[sequence_array[x].id].prior = sequence_array[x - 1].id }
    if (x < sequence_array.length - 1) { sequence[sequence_array[x].id].next = sequence_array[x + 1].id }
  }

  document.getElementById("contents").innerHTML = toc.join(``)
  //log(`sequence`,sequence)
  const html = []
  // top menu bar
  let class_clause = `class='active' `
  for (let x = 0; x < menu.length; x++) {
    if (x === 0) {
      tag("page-body").id = label_to_id(menu[x].label)
    } else {
      // we will leave the original body div for the first element of the menu and generate others
      const div = document.createElement("div")
      div.className = "content-panel"
      div.dataset.menuNumber = x
      div.style.display = "none"
      div.id = label_to_id(menu[x].label)
      tag("panels").append(div)
    }
    const menu_item = menu[x]
    if(!menu_item.hidden){
      let class_clause=""
      if(menu_item.conditional){
        //log("menu_item",menu_item)
        class_clause = ` class='conditional ${menu_item.conditional}'`
      }
      //log("class_clause",class_clause)
      html.push(`<a ${class_clause} id='menu-${x}' onclick='load_menu(${x})'${class_clause}> ${menu_item.label}</a>`)
    }
  }
  document.getElementById(`menu`).innerHTML = html.join(``)
  //log("document.getElementById(`menu`).innerHTML",document.getElementById(`menu`).innerHTML)

  // check to see if we are loged in
  if(!BookStorage.loggedIn()){
    //log("we are NOT logged in", BookStorage.loginType())
    let login_result
    switch(BookStorage.loginType()){
      case "local":
        //log("found local")
        login_result = await login_local()
        //log("login_result",login_result)
        if(login_result==="success"){
          // we have a valid login 
          message({
            message:"You are now logged in to this computer.",
            title:"Authentication Method Changed",
            seconds:8,
            show:true
          })
  
        }else if(login_result==="no login"){
          BookStorage.reset()
        }
        break
      case "gas":
        
        login_result = await login_gas()
        //log("login_result",login_result)
        if(login_result.status==="success"){
          // we have a valid login 
          message({
            message:"You are now logged in using your own authentication server.",
            title:"Authentication Method Changed",
            seconds:8,
            show:true
          })
  
        }else if(login_result==="no login"){
          BookStorage.reset()
        }
        break
      case "paid":
        break
      default: // loginType is none    
    }
  }

  let page = url_params.page
  //log("Current page",page)
  if(page==="undefined"){page="introduction"}
  //log("Current page2",page)

  // remove introduction contents
  //delete sequence["contents-0"]
  //delete sequence.introduction.prior
  
  // decide what to do when the page is loaded
  //log("about to decide what to do with the page"
  if (page === `m=0`) {
    load_page(menu[0].menu[0].page)
    //document.body.style.zoom = `200%`
    //document.getElementById(`contents`).style.zoom = `50%`
  } else if (page) {
    load_page(page, true)
  } else if (window.location.href.slice(-5) === `.html`) {
    // handle the navive link to a blog page
    //log(window.location.href.split(`/`).pop())
    load_page(window.location.href.split(`/`).pop().split(".")[0])
  } else {
    load_page(menu[0].menu[0].page)
  }



  
  configure_book()  

  

}



//==============================================================================================

function label_to_id(label) {
  return "panel-" + label.toLowerCase().split(" ").join("-").split(".").join("-")
}

function set_current_page(page_id){
  CURRENT_PAGE_ID=page_id
  BookStorage.currentPage(page_id)
}

function load_menu(menu_number) {
  
  //log(menu[menu_number],"---------------------------",menu)
  const panel = show_panel(menu[menu_number].label)
  if (panel.innerHTML.length === 0) {
    // no page has been loaded on this tab, load the index
    const page_id = "contents-" + menu_number
    load_page(page_id)
  } else {
    const page_id = panel.dataset.pageId
    history.pushState(page_id, ``, `/?${page_id}`)
    set_current_page(page_id)
    configure_book()
    //log("just loaded panel with data already on it")
  }
  
}

function proper_case(str) {
  'use strict'
  var smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|v.?|vs.?|via)$/i
  var alphanumericPattern = /([A-Za-z0-9\u00C0-\u00FF])/
  var wordSeparators = /([ :&#8211;&#8212;-])/

  return str.split(wordSeparators)
    .map(function (current, index, array) {
      if (
        /* Check for small words */
        current.search(smallWords) > -1 &&
        /* Skip first and last word */
        index !== 0 &&
        index !== array.length - 1 &&
        /* Ignore title end and subtitle start */
        array[index - 3] !== ':' &&
        array[index + 1] !== ':' &&
        /* Ignore small words that start a hyphenated phrase */
        (array[index + 1] !== '-' ||
          (array[index - 1] === '-' && array[index + 1] === '-'))
      ) {
        return current.toLowerCase()
      }

      /* Ignore intentional capitalization */
      if (current.substr(1).search(/[A-Z]|\../) > -1) {
        return current
      }

      /* Ignore URLs */
      if (array[index + 1] === ':' && array[index + 2] !== '') {
        return current
      }

      /* Capitalize the first letter */
      return current.replace(alphanumericPattern, function (match) {
        return match.toUpperCase()
      })
    })
    .join('')
}

function param(name, url = window.location.href) {
  name = name.replace(/[\[\]]/g, '\\$&');
  var regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`),
    results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/\+/g, ` `));
}

function copy_to_clipboard(elem) {
  var range = document.createRange();
  range.selectNode(elem);
  window.getSelection().removeAllRanges(); // clear current selection
  window.getSelection().addRange(range); // to select text
  document.execCommand("copy");
  window.getSelection().removeAllRanges();// to deselect
}

function toggle_code() {
  //log(header)
  // no longer using was what is passed in
  const icon = tag("toc-button")
  const code_div = tag("contents")
  if (code_div.style.display === `none`) {
    code_div.style.display = `block`
    icon.innerHTML = `expand_less`
  } else {
    code_div.style.display = `none`
    icon.innerHTML = `expand_more`
  }
}

function hide_toc() {
  // hides the table of contents
  //log("at hide_toc")
  tag("contents").style.display = `none`
  tag("toc-button").innerHTML = `expand_more`


}



function decodeHtml(html) {
  var txt = document.createElement("textarea");
  txt.innerHTML = html;
  return txt.value;
}


function tag(id) {
  return document.getElementById(id)
}



// function set_cookie(name, value, days) {//used to update cookie information
//   var expires = ``;
//   if (days) {
//     var date = new Date();
//     date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
//     expires = `; expires=` + date.toUTCString();
//   }
//   document.cookie = name + `=` + (value || ``) + expires + `; path=/`;
// }

// function get_cookie(name) {//used to retrieve cookie by name
//   var nameEQ = name + `=`;
//   var ca = document.cookie.split(`;`);
//   for (var i = 0; i < ca.length; i++) {
//     var c = ca[i];
//     while (c.charAt(0) == ` `) c = c.substring(1, c.length);
//     if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
//   }
//   return null;
// }

// function erase_cookie(name) {//used to delete a cookie by name
//   set_cookie(name, `deleted`, -2)
// }



function get_gas_endpoint(optional_gas_token) {
  //log("at get_gas_endpoint",BookStorage)
  let gas_end_point
  try {
    if(optional_gas_token){
      gas_end_point = optional_gas_token
    }else{
      gas_end_point = BookStorage.deploymentId()
    }
    //log("gas_end_point",gas_end_point)
  } catch (e) {
    message({
      message: `You attempted to execute a query using the Oracle Autonomous Database.  To do this, you must implement a Google Sheet and record the deployment ID in this book.  See <a href="/?engine-configuration">Book Configuration</a> for more details.`,
      title: "Not Fully Configured",
      seconds: 8,
      kind: "error",
      show: true
    })
    throw (e)
  }

  if (!gas_end_point) {
    return null
  }

  if (!gas_end_point.startsWith(`https://`)) {
    gas_end_point = `https://script.google.com/macros/s/${gas_end_point}/exec`
  }
  return gas_end_point
}




function download_text_file(text, filename) {
  var blob = new Blob([text], { type: "text/plain" });
  var url = window.URL.createObjectURL(blob);
  var a = document.createElement("a");
  a.href = url;
  a.download = filename;
  a.click();
}

function test_dialog(resolve_callback) {



  const body = `To execute a query using data.world, you must provide the <a href="https://data.world/settings/advanced" target="_blank">Read/Write token</a> from your account.<table style="margin-top:1rem"><tr><td>Read/Write token</td><td><input type="text" id="dwTokenEntry"></td></tr></table>`
  const title = "Token Needed"
  // const buttons=`<button onclick="set_dw_token(tag('dwTokenEntry').value); tag('overlay').remove()">OK</button>`
  const buttons = ui_button("", "Ok")
  buttons.onclick = () => {
    resolve_callback(tag('dwTokenEntry').value)
    close_dialog()
  }


  // setTimeout(()=>{
  //log("about to resolve the promise!!!!!!!!!!!!", resolve_callback)
  //   resolve_callback()
  // }, 3000)

  show_dialog({
    title: title,
    body: body,
    buttons: buttons,
    style: "max-width:500px",
  })
}



function close_dialog(){
  tag('overlay').remove()
}


function show_dialog(params){

  const overlay = ui_div()
  overlay.id = "overlay"
  overlay.className = "overlay"
  overlay.innerHTML = `<div class="modal-page"><div class="modal"  style="${params.style}"><div class="modal-title"><table><tr><td style="width:100%">${params.title}</td><td><span onclick="tag('overlay').remove()" class="material-symbols-outlined button inline-icon">close</span></td></tr></table></div><div class="modal-content">
  ${params.body}
  </div><div class="modal-footer" id="modal-footer"></div>
  </div></div>
  `

  document.body.append(overlay)
  tag("modal-footer").append(params.buttons)

}

function message(params) {
  // shows a message to the user
  //returns a reference to the message created
  // Example params{
  //     message:"Password must contain at least one Capital letter",
  //     title:"User Error",
  //     kind:"error",
  //     seconds:4,
  //     show:true
  // }
  if (params.show === false) {
    return
  }

  if (!params.title) { params.title = "Message" }
  if (!params.seconds) { params.seconds = 0 }


  let message_class = "msg-head"
  if (params.kind === "error") {
    message_class += " error"
    if (params.title === "Message") {
      params.title = "Error"
    }
  } else if (params.kind === "info") {
    message_class += " info"
  }
  const msg = document.createElement("div")
  msg.addEventListener("mouseenter", (event) => {
    event.target.dataset.permanent=true
  });
  msg.className = "message"
  msg.innerHTML = `
  <div class="${message_class}">
    ${params.title}
    <div class="msg-ctrl">
    <span onclick="close_message(this)" style="font-weight:bold" class="material-symbols-outlined button">close</span>
    </div>
  </div>
  <div class="msg-body">
  ${params.message}
  </div>`
  if (params.seconds > 0) {
    setTimeout(function () { if (!msg.dataset.permanent) { msg.remove() } }, params.seconds * 1000)
  }
  tag("message-center").appendChild(msg)
  return msg

}

function close_message(button) {
  let elem = button
  while (elem.className !== "message") {
    elem = elem.parentNode
  }
  elem.remove()
}

function message_count() {
  // reports how many messages are currently open
  return document.querySelectorAll(".message").length
}


function clear_messages() {
  //closes all message opened with the message func

  const messages = document.querySelectorAll(".message")
  log("messages",messages)
  for(let x=0;x<messages.length;x++){
    messages[x].remove()
  }
}


function configure_book() {
  // hides all conditional elements that do not include get_book_db_type() as a class
  set_book_label()

  for (const one_tag of document.querySelectorAll(".conditional")) {
    one_tag.style.display = "none"
  }

  for (const one_tag of document.querySelectorAll("." + get_book_db_type())) {
    one_tag.style.display = ""
  }
  for (const one_tag of document.querySelectorAll("." + BookStorage.aiType())) {
    one_tag.style.display = ""
  }

  //adjust prior and next links
  //log("current page id",CURRENT_PAGE_ID )
  const next_label=get_prior_next_page(CURRENT_PAGE_ID, "next")
  //log("next_label",next_label)
  if(tag("navigate-prior-label")){
    // profile page does not have navigation buttons
    tag("navigate-prior-label").innerHTML=get_prior_next_page(CURRENT_PAGE_ID, "prior").label
    if ( tag("navigate-next-label")){
      tag("navigate-next-label").innerHTML=next_label.label
    }
  }
  // color the settings person if we are logged in
  switch(BookStorage.loginType()){
    case "none":
      tag("user-login-icon").parentElement.style.backgroundColor="#888"
      break
    case "gas":
      tag("user-login-icon").parentElement.style.backgroundColor="#005cb9"
      break
    case "paid":
      tag("user-login-icon").parentElement.style.backgroundColor="darkgreen"
      break
    default://local
      tag("user-login-icon").parentElement.style.backgroundColor="purple"
  }
}





function set_book_label(text = "Table of Contents:") {
  const version = {
    "book": "SQL Standard",
    "sqlite": "SQLite",
    "dataworld": "data.world",
    "oracle": "Oracle",
  }
  //debugger
  tag("top-info").innerHTML = text + " " + version[get_book_db_type()]

}




function uuid() {
  var u = '', m = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', i = 0, rb = Math.random() * 0xffffffff | 0;
  while (i++ < 36) {
    var c = m[i - 1], r = rb & 0xf, v = c == 'x' ? r : (r & 0x3 | 0x8);
    u += (c == '-' || c == '4') ? c : v.toString(16); rb = i % 8 == 0 ? Math.random() * 0xffffffff | 0 : rb >> 4
  }
  return u
}



/**
 * Manages resources by only downloading the content from the url 
 * if it has not been cached. 
 */
const resource_manager = {
  cache: {},
  /**
   * gets the content from the URL and chaches it. if we already have it, then we just return the value
   * without making the request to the url. The url is used as the unique ID. 
   * @param url the url that we get the content from
   * @returns 
   */
  async get_post_content(url, format) {
    // const resources = BookStorage.resources.data() // get our current resources
    const resources = this.cache
    if (resources[url] === undefined) {
      const content = await get_post_content(url, format)
      resources[url] = content // update current resources with new url
      // BookStorage.resources.data(resources) // save into local storage
      this.cache = resources
    }
    return resources[url]
  },
}

function show_hourglass(element, show) {
  //replaces the innerhtml of element with a blinking hourglass and remembers what the html used to be
  // or restores the original content if show = "restore"
  // returns false of element is already showing hourglass
  const hourglass = `<span class="material-symbols-outlined blink" style="vertical-align:middle">hourglass_empty</span>`


  if (show === 'restore') {
    element.innerHTML = atob(element.dataset.original_content)
  } else if (element.innerHTML === hourglass) {
    return false
  } else {
    element.dataset.original_content = btoa(element.innerHTML)
    element.innerHTML = hourglass
  }

  return true

}

async function set_server_property(params) {
  // sets or gets a propert on the google backend.  Can be modified to work with other backends when we have them
  // params needs:
  //   "key" property with with name of the data object to be read or modified
  //   "dataArray" prperty that has whatever value you want to store.  If you
  //               pass an id, as part of an array entry, it will overwrite
  //               an existing entry with the same id 
  // example data array
  // [{name:"admin connection",
  // username:"admin", 
  // password:"password.12345", 
  // url:"https://cloud.oracleapps.com/yada/yada", 
  // protect:true,
  // id:"b8e226bb-4393-40e6-b957-460826e3f652" 
  // }]

  return await server_post({
    "mode": "property",
    "action": "set",
    "key": params.key,
    "dataArray": params.dataArray,
  })

}

async function get_server_property(params) {
  // sets or gets a propert on the google backend.  Can be modified to work with other backends when we have them
  // params needs:
  //   "key" property with with name of the data object to be read or modified
  //   "ids" property with an array of hte ids you want retrieve,  omit to get all

  return await server_post({
    "mode": "property",
    "action": "get",
    "key": params.key,
    "ids": params.ids,
  })

}

async function test_get_server_props() {
  const response = await server_property({
    action: "get",
    key: "oracle_connections",
    ids: ["sql_book_connection"]
  })
  //log(response)
}


async function get_student_data_values() {
  let data = await get_server_property({
    action: "get",
    key: "data",
    ids: ["student_data"]
  })

  if (data.status === "failure") {
    data = {}
  } else {
    data = data.property.student_data.obj
  }
  simple_add("studentId")
  simple_add("firstName")
  simple_add("lastName")
  simple_add("email")
  simple_add("classKey")
  simple_add("dwToken")

  //log("data", data)

  tag("data-object").innerHTML = btoa(JSON.stringify(data))

  function simple_add(id) {// just calls the next two function with only an id
    add_if_missing(id)
    val_to_form(id)
  }

  function val_to_form(tag_id, data_id) {//read value from data in push to form, replace with tagid
    if (!data_id) { data_id = tag_id }
    tag(tag_id).value = data[data_id]
    data[data_id] = tag_id

  }
  function add_if_missing(id, value = "") {
    if (data[id] === undefined) {
      data[id] = value
    }
  }

}

async function signUserInModal() {
  //log("user sing in modal")
  try {
    return await new Promise((resolve, reject) => {
      const overlay = ui_div("overlay")
      overlay.id = "overlay"

      const modal_x = ui_span("material-symbols-outlined button inline-icon", "close")
      modal_x.onclick = () => {
        overlay.remove()
        reject("user abort")
      }
      const modal_title = ui_div("modal-title", "Signup", modal_x)

      const modal_content = ui_div("modal-content p3",
        ui_auth_form(resolve, reject)
      )

      const modal_footer = ui_div("modal-footer", "foot")
      const modal = ui_div("modal", modal_title, modal_content, modal_footer)
      const modal_page = ui_div("modal-page", modal)

      overlay.append(modal_page)
      document.body.append(overlay)
    })
  } catch (error) {
    // auth failed!
    console.error("auth has failed, or user gave up")
    throw error
  }
}


function user_menu(icon){
  // loads the user login page
  //log(icon)
  load_page("user-profile")
}



function show_user_menu(evt) {
  // shows the user menu in the upper right corner


  const rect = tag("panels").getBoundingClientRect()
  
  const menu = document.createElement("div")
  menu.id="menu-overlay"
  menu.className = "overlay-menu"
  
  let logout_display="none"
  let clear_data_display="block"
  let login_display="block"

  if(BookStorage.loggedIn() && BookStorage.loginType()!=="none"){
    logout_display="block"
    clear_data_display="none"
    login_display="none"
  }


  menu.innerHTML = `
  <div class="user-menu" style="margin-top:${tag('menu').clientHeight}px; margin-left:${rect.right-200}px">
    <div class="user-menu-item" onclick="abandon_machine()" style="display:${clear_data_display}">Clear All Data</div>
    <div class="user-menu-item" onclick="show_login_form()" style="display:${login_display}">Log In</div>
    <div class="user-menu-item" onclick="BookStorage.logout()" style="display:${logout_display}">Log out</div>
    <div class="user-menu-item" onclick="load_page('setup-wizard')">Settings</div>
  </div>`
  
  
  tag("panels").appendChild(menu)
 
  tag('menu-overlay').addEventListener('click', function (event) {
    tag('menu-overlay').remove()
  });

}


function toggle_next_row(element_clicked){
  let elem = element_clicked
  while (elem.tagName.toUpperCase() !== 'TR') {
    elem = elem.parentNode
  }
  elem=elem.nextElementSibling
  if(elem.style.display==="none"){
    elem.style.display=""
  }else{
    elem.style.display="none"
  }

}


function save_course_data(){
  // does saces the stduent data
  message({
    message: "yep, we need to figure out how to save coruse data.  It's on the list",
    title: "Not yet implemented",
    seconds: 8,
    kind: "error",
    show: true
  })
}

function ncrypt(data, key){
  // uses sjcl to encrypt a string
  if(data===null){return null}
  if(key){
    return JSON.parse(sjcl.encrypt(key,data,{"iv":"5zm0Jejo259XOOjbEDSpOA==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"0szHqYwXgcY="})).ct
  }else{
    return data
  }
}

function dcrypt(data, key){
  // decrypts a string that was encrypted with ncrypt 
  if(data===null){return null}
  if(key){
    try{
      return sjcl.decrypt(key,JSON.stringify({"iv":"5zm0Jejo259XOOjbEDSpOA==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"0szHqYwXgcY=","ct":data}))
      }catch(e){
        return("failed")
      }
  }else{
    return data
  }

}



function bookstorage_to_object(stringify=false){
  //returns all values in bookStorage as an object or json string
  const obj={}
  for(const key of BookStorage.getKeys()){
    try{
    obj[key] = BookStorage[key]()
    }catch(e){
      if(e.name!=="AutoStorageNullValueError"){
        throw e
      }
    }
  }



  if(stringify){
    return JSON.stringify(obj)
  }else{
    return obj
  }
}

function object_to_bookstorage(object_or_json_string){
  //loads an object or json string into book strorage.  object_or_json_string is produced by bookstorage_to_object
  const obj=(
    typeof object_or_json_string === "string"
    ?
    JSON.parse(object_or_json_string)
    :
    object_or_json_string
  )


  if(obj.token){
    BookStorage.token(obj.token)
    delete obj.token
  }  

  if(obj.LocalToken){
    BookStorage.LocalToken(obj.LocalToken)
    delete obj.LocalToken
  }  
  if(obj.canary){
    BookStorage.canary(obj.canary)
    delete obj.canary
  }  

  for(const [key,val] of Object.entries(obj)){
    if(typeof BookStorage[key]==="function"){
      // log("changing",key,val, "aiType", BookStorage.aiType())
      BookStorage[key](val)
      // log("changed",key,val, "aiType", BookStorage.aiType())
      //debugger
    }
  }
  log("restoring ai type",BookStorage.aiType())
  
}



function get_data_from_element(element, input_ids_to_exclude=[]){
  // get's the values and names of all input tags in the element
  // written for pulling data from user-profile, but should work anywhere
  const key_value_pair_object={}
  for(const input of element.getElementsByTagName("input")){
    const var_name = id_to_variable_name(input.id)
    if(!input_ids_to_exclude.includes(input_ids_to_exclude)){
      key_value_pair_object[var_name]=input.value
    }
  }
  return key_value_pair_object
}

function get_id_map_from_element(element, input_ids_to_exclude=[]){
  // retrns a map of ids of the inputs in element
  // {studentId:"student-id",studentFirstName:"student-first-name"}
  const key_value_pair_object={}
  for(const input of element.getElementsByTagName("input")){
    const var_name = id_to_variable_name(input.id)
    if(!input_ids_to_exclude.includes(input_ids_to_exclude)){
      key_value_pair_object[var_name]=input.id
    }
  }
  return key_value_pair_object
}

function id_to_variable_name(id) {
  //takes a compound-object-id and returns compoundObjectId
  //log(id, id.length)
  if(id){
  s = id.split('-')
  .map(w => w[0].toUpperCase() + w.substring(1).toLowerCase())
  .join('')
  return s[0].toLowerCase() + s.slice(1)
  }
}

function close_message(element_clicked){
  // closes a message in the messagecenter.  Call this from the click even inside a message to close it.
  //log(element_clicked)
  let elem = element_clicked
  while (elem.className !== 'message') {
    elem = elem.parentNode
  }
  elem.remove()

}


function debug(on_off_blank){
  // a debugging function.  put debug() somewhere in your code
  // it stays dormant until you execute debug("on") , then it will
  //take you to break mode.  execute debug("off"), to make dormant

  switch(on_off_blank){
    case 1:
    case "on":
      window.stop_for_debug=true
      return "The js-debugger will now be invoked by debug() statements in your code"
    case 0:
    case "off":
      window.stop_for_debug=false
      return "The js-debugger is now dormant"
    default:
      if(window.stop_for_debug){
        ;debugger
      }
  }
}

/**
 * ensures the user is signed in. Will throw an empty error if the user does not sign in. 
 * @returns {Promise<FirebaseUser?>} undefined
 */
async function getUser(showModal=true) {
  //log("getting user")
  const auth = firebase.auth.getAuth();
  return await new Promise((resolve) => {
      const overlay = ui_modal("Please Sign In", ui_auth_form(), resolve)
      firebase.auth.onAuthStateChanged(auth, async (user) => {
          if (!user) {
            if (showModal) {
              document.body.append(overlay)
            }else{
              resolve(null)
            }
          } else {
              overlay.remove()
              resolve(user)
          }
      })
  })
}

/**
 * tells us if the user is logged in. 
 * @returns {boolean} true if the object is not null
 */
function userIsLoggedIn(){
  return firebase.auth.getAuth().currentUser ? true : false
}

/**
* gets the size on bytes of a given string
* @param {string }str string to get size in bytes from
* @returns number of bytes in the string
*/
function byteSize(str) {
  return new Blob([str]).size;
}

/**
 * Returns a promise you can use to wait for a spesific amount of time.
 * @param {number} sec number of seconds to wait
 * @returns n
 */
function wait(sec){
  return new Promise((resolve) => {
    setTimeout(resolve, sec*1000)
  })
}

function debounce(func, timeout = 300) {
  let timer
  return (...args) => {
    clearTimeout(timer)
    timer = setTimeout(() => { func(...args) }, timeout)
  }
}

function log(...args){
  // use this to log only in development mode
  if(DEVELOPMENT_MODE)console.log(...args)
  //console.log(...args)
}

function toggle_video(object_clicked, parent_tag_name="div"){
  // looks up from object_clicked to find parent_tag_div then finds the first iframe and makes it visible, and makes it 100% wide, maintaining its aspect ratio
  let elem = object_clicked
  while (elem.tagName.toUpperCase() !== parent_tag_name.toUpperCase()) {
    elem = elem.parentNode
  }
  const target=elem.querySelector("iframe")
  if(target.style.display==="none"){
    let ratio=9/16
    if(target.height && target.width){
      ratio = target.height/target.width
    }
    target.style.display=""
    target.style.width = "100%"
    target.style.height = (target.clientWidth * ratio) + "px"
    target.focus()
  }else{
    target.style.display="none"
  }

}

async function config_from_link(){
  // invoked when config page is loaded.  Takes the parameter from the url and sets the BookStorage.submission data then redriects to setup wizard with the config code
  const query_string = window.location.href.split(`?`)[1]
  const url_params = get_params(query_string)
  window.sessionStorage.setItem("configData",url_params.data)
  //tag("config-output").innerHTML=JSON.stringify(JSON.parse(web_safe_base64_decode(url_params.data)),null,4)
  const data=JSON.parse(b64DecodeUnicode(url_params.data.replace(/_/g, '/').replace(/-/g, '+')))


 window.location.replace("/?page=setup-wizard&code="+data.code)
//tag("config-output").innerHTML=JSON.stringify(data,null,4)
  //console.log(b64DecodeUnicode(url_params.data.replace(/_/g, '/').replace(/-/g, '+')))// convert web safe chars then do a utf-8 decode
}

