anchor.diff:        after_action :allow_iframe, only: [:launch, :resource]
       </pre>
   
  -    We will begin with explanation of launch endpoint here. Once OpenDSA
  -    content is added into a course and a student clicks on an OpenDSA
  -    exercise, it sends an LTI request to the launch endpoint.
  -    Within the launch endpoint, it first validates if 'custom_inst_book_id' is
  -    available or not. This is a custom parameter, and it checks if this
  -    parameter is available then the custom book instance was created on OpenDSA
  -    website and modules were created using Canvas API. If the book instance is
  -    not present, it calls the endpoint 'launch_ex' which means that it is a
  -    standalone exercise.<br><br>
  +    We will begin with explanation of launch endpoint here. Click
  +    <%= link_to "here", lti_opendsa_instructor_path %> to read how OpenDSA
  +    handles LTI requests when instructors add exercises to their courses.
  +    <br><br>
  +
  +    Once OpenDSA content is added into a course and a student clicks on an
  +    OpenDSA exercise, Tool Consumer sends an LTI request to the launch endpoint
  +    of OpenDSA. Within the launch endpoint, OpenDSA initially validates if 'custom_inst_book_id' is available or not. This is a custom parameter, which if available means that the OpenDSA book instance was created on OpenDSA's website and modules were created in Canvas using Canvas API. If the book instance is not present, it means that this is a standalone exercise and OpenDSA calls the endpoint 'launch_ex' to handle standalone exercise. <br><br>
       <pre>
         unless params.key?(:custom_inst_book_id)
           launch_ex
  
positive.code:       end
      </pre>
  
      Now first we will cover launch_ex endpoint <strong> which means a standalone
      exercise is launched by the student.</strong> To add standalone graded
      exercises in your course follow the steps mentioned
      <%= link_to "here", lti_instructions_opendsa_path %>.<br><br>
  
      When a student clicks on an assignment, first steps that are performed are
      that it first fetches credentials (unique secret) from public
      authentication key received in a request and find course offering to which
      assignment belongs.<br><br>
      <pre>
      def launch_ex
        require 'oauth/request_proxy/rack_request'
  
negative.code:       end
      </pre>
  
      Once the request has been validated, OpenDSA returns back to the
      <em>"launch_ex"</em> endpoint and calls <em>"ensure_user"</em> method after
      that.<br><br>
      <pre>
        ensure_user()
      </pre>
  
      Within 'ensure_user' method, OpenDSA checks if a user with the same email
      exists or not and creates a new user if that email is not found and
      finally, signs in that user to start his session.<br><br>
      <pre>
        def ensure_user
          email = params[:lis_person_contact_email_primary]
  