anchor.diff:                                  None
                               else
                                   try Some (spl.[0], Some (SemVer.Parse spl.[1]))
  -                                with e -> 
  +                                with e ->
                                       eprintfn "Failed to parse @type '%s' in nuget v3: %O" res e
                                       None
                           | _ ->
                               if verbose then
                                   eprintfn "Unable to parse @type in nuget v3: '%s'" res
                               None
  -                    match name_version with 
  +                    match name_version with
                       | None -> None
                       | Some (name, version) ->
                           let resType =
  
positive.code: 
          let catalogData = relevantPage.PackageDetails
          let dependencyGroups, dependencies =
              if catalogData.DependencyGroups = null then
                  [], []
              else
                  let detect x =
  
negative.code:         | Some str when str = normalized -> str
          | Some str -> str + "!" + normalized
          | None -> normalized + "!!"
  
      versions
      |> List.distinct
      |> List.map getSemVer
      |> List.sort
      |> List.map semVerStr
  
  let private semVerOrder2 _ versions = semVerOrder versions
  
  //let private
  
  let getCatalogCursor basePath serviceUrl =
      let hostName = getHostSpecificFileName serviceUrl
      let fullName = Path.Combine(basePath, hostName + ".txt")
  
      let mutable packName = ""
      let mutable versions = List.empty
  
      let mutable builder = {
          Source = serviceUrl
          Cursor = DateTimeOffset.MinValue
          Packages = Seq.empty |> Map.ofSeq
      }
  
      if File.Exists fullName then
          let readLine = File.ReadLines fullName
          for line in readLine do // deserialize
              match line with
              | null | "" -> ignore() // skip empty
  
              | a when a.[0] = ':' ->
                  let cursor = a.Substring(1).Trim()
                  match DateTimeOffset.TryParse cursor with
                  | true, cursor -> builder <- {
                      builder with Cursor = cursor}
                  | false, _ -> ignore()
  
              | a when a.[0] = '*' ->
                  match packName with
                  | null | "" -> ignore()
                  | name ->
                      let ver =
                          match Map.tryFind name builder.Packages with
                          | Some values -> versions @ values
                          | None -> versions
  
                      builder <- {
                          builder with
                              Packages = builder.Packages.Add(name,ver)}
  
                  versions <- List.empty // cleanup
                  packName <- a.Substring(1).Trim()
  
              | a when a.[0] = '`' -> ignore()
              | a when a.[0] = '.' -> ignore()
              | a when a.[0] = ',' -> ignore()
              | a when a.[0] = ';' -> ignore()
              | a when a.[0] = '>' -> ignore()
              | a when a.[0] = '<' -> ignore()
              | a when a.[0] = '/' -> ignore()
              | a when a.[0] = '\\' -> ignore()
              | a when Char.IsControl(a.[0]) -> ignore()
              | a when Char.IsSeparator(a.[0]) -> ignore()
              | a when Char.IsWhiteSpace(a.[0]) -> ignore()
  
              | version -> versions <- version :: versions
      else
          ignore()
      let catalog = {
          builder with
  