(FILECREATED "13-Mar-87 19:16:22" {QV}<NOTECARDS>1.3K>NEXT>RHTPATCH215.;6 50217  

      changes to:  (FNS NC.CompactNoteFileToTarget NC.CompactNoteFileInPlace NC.DeleteNoteCards 
			NC.SeverAllLinks NC.SeverExternalLinks NC.DeleteFromLink NC.DeleteToLink 
			NC.DeleteLink NC.GetPropList NC.GetMainCardData NC.GetTitle NC.GetLinks 
			NC.DeleteNoteCardInternal)
		   (VARS RHTPATCH215COMS)

      previous date: "13-Mar-87 11:47:25" {QV}<NOTECARDS>1.3K>NEXT>RHTPATCH215.;1)


(* Copyright (c) 1987 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT RHTPATCH215COMS)

(RPAQQ RHTPATCH215COMS ((* * Changes to fix bug reported by Julian where deleting 90% of cards in a 
			     notfile quadrupled the space used by the notefile.)
			  (* * This function should be deleted from NCCARDS)
			  (FNS NC.SeverAllLinks)
			  (* * New function for NCCARDS)
			  (FNS NC.SeverExternalLinks)
			  (* * Changes to NCCARDS)
			  (FNS NC.DeleteNoteCards NC.DeleteNoteCardInternal)
			  (* * This function should be deleted from NCLINKS)
			  (FNS NC.SmartDeleteLinks)
			  (* * New functions for NCLINKS)
			  (FNS NC.DeleteFromLink NC.DeleteToLink)
			  (* * Changes to NCLINKS)
			  (FNS NC.DeleteLink)
			  (* * Changes to NCDATABASE)
			  (FNS NC.GetLinks NC.GetPropList NC.GetMainCardData NC.GetTitle)
			  (* * Changes to NCCOMPACT)
			  (FILES (FROM NOTECARDS)
				 NCCOMPACT)
			  (FNS NC.CompactNoteFileToTarget NC.CompactNoteFileInPlace)))
(* * Changes to fix bug reported by Julian where deleting 90% of cards in a notfile quadrupled
 the space used by the notefile.)

(* * This function should be deleted from NCCARDS)

(DEFINEQ

(NC.SeverAllLinks
  (LAMBDA (ListOfCards QuietFlg InterestedWindow)            (* rht: "13-Mar-87 16:34")

          (* * Delete all links into and out of any cards in ListOfCards. Furthermore, do it efficiently by caching a card 
	  only long enough to delete all the links between it and ListOfCards.)



          (* * rht 12/16/86: Removed obsolete Don'tPutToBeDeletedCardsFlg arg.)



          (* * rht 3/13/87: Changed to only delete "external" links, i.e. those into or out of ListOfCards.
	  Note that we depend on the fact that every card in ListOfCards has its AboutToBeDeletedFlg set.)


    (OR QuietFlg (NC.PrintMsg InterestedWindow T "Gathering links of " (LENGTH ListOfCards)
				  " cards."))
    (NC.SmartDeleteLinks (NC.UnionListsOfLinks (for Card in ListOfCards
						      join
						       (for Link in (NC.RetrieveToLinks Card)
							  unless (NC.UIDGetProp
								     (fetch (Card UID)
									of (fetch (Link 
										  DestinationCard)
										of Link))
								     (QUOTE AboutToBeDeletedFlg))
							  collect Link))
						   (for Card in ListOfCards
						      join
						       (for Link in (NC.RetrieveFromLinks
									  Card)
							  unless (NC.UIDGetProp
								     (fetch (Card UID)
									of (fetch (Link 
										       SourceCard)
										of Link))
								     (QUOTE AboutToBeDeletedFlg))
							  collect Link)))
			   QuietFlg InterestedWindow)))
)
(* * New function for NCCARDS)

(DEFINEQ

(NC.SeverExternalLinks
  (LAMBDA (ListOfCards QuietFlg InterestedWindow)            (* rht: "13-Mar-87 16:49")

          (* * Delete all links in ListOfCards to or from cards not in ListOfCards. Furthermore, do it efficiently by caching
	  an external card only long enough to delete all the links between it and ListOfCards. Note that we depend on the 
	  fact that every card in ListOfCards has its AboutToBeDeletedFlg set.)


    (LET (LinksToSever NumLinksToSever)
         (OR QuietFlg (NC.PrintMsg InterestedWindow T "Gathering external links of "
				       (LENGTH ListOfCards)
				       " cards."))
         (SETQ LinksToSever (NC.UnionListsOfLinks
	     (for Card in ListOfCards join (for Link in (NC.RetrieveToLinks Card)
						    unless (NC.UIDGetProp
							       (fetch (Card UID)
								  of (fetch (Link DestinationCard)
									  of Link))
							       (QUOTE AboutToBeDeletedFlg))
						    collect Link))
	     (for Card in ListOfCards join (for Link in (NC.RetrieveFromLinks Card)
						    unless (NC.UIDGetProp
							       (fetch (Card UID)
								  of (fetch (Link SourceCard)
									  of Link))
							       (QUOTE AboutToBeDeletedFlg))
						    collect Link))))

          (* * Now sort links so that links with same external anchor card are grouped together. Furthermore, the links 
	  having that anchor card has source card are grouped before the ones having that card as destination card.)


         (OR QuietFlg (NC.PrintMsg InterestedWindow T "Sorting " (SETQ NumLinksToSever
					 (LENGTH LinksToSever))
				       " links prior to severing."))
         (SORT LinksToSever (FUNCTION (LAMBDA (Link1 Link2)
		     (LET (DestCard1 DestCard2 ExtCard1 ExtCard2 Link1SourceIsExtFlg)
		          (SETQ ExtCard1 (if (NC.UIDGetProp (fetch (Card UID)
								     of (SETQ DestCard1
									    (fetch (Link 
										  DestinationCard)
									       of Link1)))
								  (QUOTE AboutToBeDeletedFlg))
					       then (SETQ Link1SourceIsExtFlg T)
						      (fetch (Link SourceCard) of Link1)
					     else DestCard1))
		          (SETQ ExtCard2 (if (NC.UIDGetProp (fetch (Card UID)
								     of (SETQ DestCard2
									    (fetch (Link 
										  DestinationCard)
									       of Link2)))
								  (QUOTE AboutToBeDeletedFlg))
					       then (fetch (Link SourceCard) of Link2)
					     else DestCard2))
		          (if (NC.SameCardP ExtCard1 ExtCard2)
			      then Link1SourceIsExtFlg
			    else (LESSP (fetch (Card IndexLoc) of ExtCard1)
					    (fetch (Card IndexLoc) of ExtCard2)))))))

          (* * Now walk down the list of links one by one activating the external anchor cards as needed.)


         (OR QuietFlg (NC.PrintMsg InterestedWindow T "Severing links: 1 out of " NumLinksToSever 
				       " ..."))
         (for Link in LinksToSever as i from 1 bind PreviousExtCard WasNotActiveFlg
	    eachtime (BLOCK) when (NC.ValidLinkP Link)
	    do (OR QuietFlg (if (ZEROP (REMAINDER i 10))
				    then (NC.PrintMsg InterestedWindow T "Severing links: " i 
							  " out of "
							  NumLinksToSever " ...")))
		 (LET (ExtCard ExtCardIsSourceFlg)
		      (SETQ ExtCard (if (NC.UIDGetProp (fetch (Card UID)
								of (fetch (Link DestinationCard)
									of Link))
							     (QUOTE AboutToBeDeletedFlg))
					  then (SETQ ExtCardIsSourceFlg T)
						 (fetch (Link SourceCard) of Link)
					else (fetch (Link DestinationCard) of Link)))
		      (if (NOT (NC.SameCardP ExtCard PreviousExtCard))
			  then                             (* Write down changes to previous external card's 
							     substance.)
				 (if WasNotActiveFlg
				     then                  (* Have to call NC.CardSaveFn first and then 
							     NC.QuitCard with Don'tSaveFlg to avoid 
							     insureProperFiling check.)
					    (NC.CardSaveFn PreviousExtCard T)
					    (NC.QuitCard PreviousExtCard NIL T NIL NIL NIL T))
                                                             (* If ExtCard not active, then cache.)
				 (if (SETQ WasNotActiveFlg (NOT (NC.ActiveCardP ExtCard)))
				     then (if ExtCardIsSourceFlg
						then       (* Cache whole card if it's the link's source.)
						       (NC.GetNoteCard ExtCard)
					      else         (* Else only need the links since we're deleting the 
							     from link.)
						     (NC.GetLinks ExtCard))))
                                                             (* Delete the appropriate half of the link.)
		      (if ExtCardIsSourceFlg
			  then (NC.DeleteToLink Link)
			else (NC.DeleteFromLink Link))
		      (replace (Link UID) of Link with -1)
		      (SETQ PreviousExtCard ExtCard))
	    finally (if (AND WasNotActiveFlg (NC.ValidCardP PreviousExtCard))
			  then                             (* Have to call NC.CardSaveFn first and then 
							     NC.QuitCard with Don'tSaveFlg to avoid 
							     insureProperFiling check.)
				 (NC.CardSaveFn PreviousExtCard T)
				 (NC.QuitCard PreviousExtCard NIL T NIL NIL NIL T))))))
)
(* * Changes to NCCARDS)

(DEFINEQ

(NC.DeleteNoteCards
  (LAMBDA (CardIdentifiers NoIndividualConfirmFlg DontClearFlg InterestedWindow QuietFlg 
			   NoGroupConfirmFlg)                (* rht: "13-Mar-87 19:16")
                                                             (* Delete note cards. If no card specified then get a 
							     list of note cards to be deleted.
							     Then delete these cards.)

          (* * fgh 11/11/85: Updated to handle new Card objects. Also split off main work of deleteing a single note card 
	  into NC.DeleteNoteCard function.)



          (* * kirk 21Feb86 Added InterestedWindow)



          (* * kirk 29Apr86 Now returns CardIdentifiers)



          (* * fgh 6/9/86 Added checks to see if other operations are in progress)



          (* * rht 7/4/86: Now checks that card is not read-only.)



          (* * kirk 18Aug86 Added main window for windowless cards.)



          (* * rht 8/29/86: Reorganized and added call to NC.SeverAllLinks to make deleting more efficient.
	  Added QuietFlg, NoGroupConfirmFlg and Don'tPutToBeDeletedCardsFlg args.)



          (* * rht 9/5/86: Now forces NoGroupConfirmFlg to be non-nil if NoIndividualConfirmFlg is NIL and only one card to 
	  delete.)



          (* * pmi 12/5/86: Modified message to NC.SelectNoteCards to mention SHIFT-selection.)



          (* * pmi 12/12/86: Removed obsolete ReturnLinksFlg argument in call to NC.SelectNoteCards.)



          (* * rht 12/16/86: Removed obsolete Don'tPutToBeDeletedCardsFlg arg.)



          (* * rht 3/9/87: Changed NC.DeleteSelectingMenu to NC.SelectingCardsMenu.)



          (* * rg 3/9/87 added NC.ProtectedSessionOperation wrapper)



          (* * rg 3/11/87 changed call of NC.DeleteNoteCard to NC.DeleteNoteCardInternal)


    (DECLARE (GLOBALVARS NC.SelectingCardsMenu))
    (NC.ProtectedSessionOperation
      "Delete Note Cards" InterestedWindow (OR CardIdentifiers (SETQ CardIdentifiers
						   (NC.SelectNoteCards NIL NIL 
									 NC.SelectingCardsMenu 
									 InterestedWindow 
					      "Please shift-select the Note Cards to be deleted.")))

          (* * Kludge in case args are nil, say, when we're called from a card's menu.)


      (if (AND (NULL NoIndividualConfirmFlg)
		   (NULL NoGroupConfirmFlg)
		   (EQ (LENGTH (MKLIST CardIdentifiers))
			 1))
	  then (SETQ NoGroupConfirmFlg T)
		 (SETQ QuietFlg T))

          (* * First collect cards that are deletable.)


      (LET ((CardsToDelete (for CardIdentifier in (MKLIST CardIdentifiers) bind Card
			      eachtime (BLOCK)
			      when (AND (SETQ Card (NC.CoerceToCard CardIdentifier))
					    (if (NOT (NC.TopLevelCardP Card))
					      else (NC.PrintMsg (NC.FetchWindow Card)
								    T 
								"You cannot delete this FileBox."
								    (CHARACTER 13))
						     (DISMISS 1000)
						     (NC.ClearMsg (NC.FetchWindow Card)
								    T)
						     NIL)
					    (NC.CheckForNotReadOnly Card (NC.FetchWindow Card)
								      "Can't delete cards from a ")
					    (OR NoIndividualConfirmFlg
						  (PROG1 (NC.AskYesOrNo 
							  "Are you sure you want to delete this?"
									    " -- " "Yes"
									    (NULL DontClearFlg)
									    (OR (NC.FetchWindow
										    Card)
										  InterestedWindow)
									    NIL NIL)
							   (NC.ClearMsg))))
			      collect Card))
	    (NumSpecified (LENGTH (MKLIST CardIdentifiers)))
	    NumToDelete)
           (SETQ NumToDelete (LENGTH CardsToDelete))
           (if (AND (GREATERP NumToDelete 0)
			(if (EQUAL NumToDelete NumSpecified)
			    then (OR NoGroupConfirmFlg (PROG1 (NC.AskYesOrNo
								      (CONCAT "You've specified " 
										NumToDelete 
									      " cards to delete."
										(CHARACTER 13)
										
							 "Are you sure you want to delete them? ")
								      NIL "Yes" (NULL DontClearFlg)
								      InterestedWindow)
								    (NC.ClearMsg)))
			  else (PROG1 (NC.AskYesOrNo (CONCAT "Out of " NumSpecified 
								     " cards specified, "
								     (DIFFERENCE NumSpecified 
										   NumToDelete)
								     " are not deletable."
								     (CHARACTER 13)
								     "Want to delete the remaining " 
								     NumToDelete " cards? ")
							   NIL "Yes" (NULL DontClearFlg)
							   InterestedWindow)
					  (NC.ClearMsg))))
	       then 

          (* * Mark UIDs of cards about to be deleted.)


		      (for Card in CardsToDelete do (NC.UIDPutProp (fetch (Card UID)
									      of Card)
									   (QUOTE 
									      AboutToBeDeletedFlg)
									   T))

          (* * Sever all links into and out of CardsToDelete)


		      (NC.SeverExternalLinks CardsToDelete QuietFlg InterestedWindow) 

          (* * Now delete the cards one at a time.)


		      (OR QuietFlg (NC.PrintMsg InterestedWindow T "Deleting cards: 1 out of " 
						    NumToDelete " ..."))
		      (for Card in CardsToDelete as i from 1 eachtime (BLOCK)
			 do (OR QuietFlg (if (ZEROP (REMAINDER i 10))
						 then (NC.PrintMsg InterestedWindow T 
								       "Deleting cards: "
								       i " out of " NumToDelete 
								       " ...")))
			      (NC.ProtectedCardOperation Card "Delete Card" InterestedWindow
							 (NC.DeleteNoteCardInternal Card T 
										 InterestedWindow T)))
		      (OR QuietFlg (NC.ClearMsg InterestedWindow T))
		      CardIdentifiers)))))

(NC.DeleteNoteCardInternal
  (LAMBDA (Card QuietFlg InterestedWindow IgnoreLinksFlg)    (* rht: "13-Mar-87 16:32")

          (* * Delete a single note card from a NoteFile)



          (* * rht 8/11/86 Now calls NC.DeleteReferencesToCardFromShowLinks to smash any link icons in show links menus 
	  pointing to this card.)



          (* * kef 7/28/86: Added code to obtain all of the write locks deemed necessary.)



          (* * kef 7/30/86: Modified to check for Client's concept of whether he owns the write lock or not, thus deciding 
	  whether or not to setup the release of the write lock afterwards.)



          (* * kef 7/31/86: Added the nesting of the obtaining writelocks with deactivating the card.)



          (* * fgh 8/30/86 Translated APPLY* to NC.ApplyFn. Made cosmetic changes in FOR loop concewrning WriteLocks.)



          (* * rht 1/16/87: Moved call to MarkCardDeletedFn after call to NC.QuitCard.)



          (* * rg 3/11/87 renamed)



          (* * rht 3/13/87: Added QuietFlg, InterestedWindow, and IgnoreLinksFlg args. The latter non-nil causes card 
	  deletion but no link cutting.)


    (RESETLST (RESETSAVE (CURSOR WAITINGCURSOR))
		(RESETSAVE NIL (BQUOTE (NC.SetBeingDeletedFlg , Card NIL)))
		(WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
			      (LET ((WriteLocks (for CardPart
						   in (QUOTE (SUBSTANCE TITLE TOLINKS FROMLINKS 
									    GLOBALTOLINKS PROPLIST))
						   collect (CONS Card CardPart)))
				    ToLinks FromLinks Window BusyPart)
			           (OR InterestedWindow (SETQ InterestedWindow
					   (NC.AttachPromptWindow (NC.FetchWindow Card))))
			           (NC.SetBeingDeletedFlg Card T)
			           (if (NOT IgnoreLinksFlg)
				       then (SETQ ToLinks (NC.RetrieveToLinks Card))
					      (SETQ FromLinks (NC.RetrieveFromLinks Card))
					      (for ToLink in ToLinks
						 do (NCONC WriteLocks
							       (for CardPart
								  in (QUOTE (TOLINKS FROMLINKS 
										    GLOBALTOLINKS))
								  collect
								   (CONS (fetch (Link 
										  DestinationCard)
									      of ToLink)
									   CardPart))))
					      (for FromLink in FromLinks
						 do (NCONC WriteLocks
							       (for CardPart
								  in (QUOTE (SUBSTANCE TOLINKS 
											FROMLINKS 
										    GLOBALTOLINKS))
								  collect
								   (CONS (fetch (Link SourceCard)
									      of FromLink)
									   CardPart)))))

          (* * The for... loop that follows is the condition that we can obtain all of the write locks on all of the card 
	  parts collected in WriteLocks. If we obtain a writelock, setup a RESETSAVE to release it upon exit.
	  Then finally, if we do obtain a write lock, return T so that the for loop's "always" condition is satisfied.
	  If we don't obtain a write lock for a given card part, save that one as a variable so we can report it to the user.
	  Then return NIL, so that the for loop's "always" condition is not satisfied, and we bump out of the for loop.)


			           (OR QuietFlg (NC.PrintMsg InterestedWindow T 
								 "Collecting write locks..."))
			           (COND
				     ((for WriteLock in WriteLocks bind WLCard WLCardPart
					 when (NC.ValidCardP (SETQ WLCard (CAR WriteLock)))
					 always (SETQ WLCardPart (CDR WriteLock))
						  (COND
						    ((NC.ApplyFn ObtainWritePermissionFn WLCard 
								 WLCardPart)
						      (RESETSAVE NIL
								   (BQUOTE
								     (APPLY* , (fetch
										 (Card 
									 ReleaseWritePermissionFn)
										    of WLCard)
									       , WLCard , WLCardPart))
								   )
						      T)
						    (T (SETQ BusyPart WriteLock)
						       NIL)))

          (* * Call off to the MarkCardDeletedFn specific to the NoteFile.)


				       (RESETSAVE (for CardPart
						       in (QUOTE (SUBSTANCE TOLINKS GLOBALTOLINKS 
										PROPLIST))
						       do (NC.ApplyFn ObtainWritePermissionFn Card 
									CardPart))
						    (BQUOTE (NC.DeactivateCard , Card T)))
				       (NC.ApplyFn MarkCardDeletedFn Card)
				       (NC.SetToLinks Card NIL)
				       (NC.SetFromLinks Card NIL)
				       (if (NOT IgnoreLinksFlg)
					   then (OR QuietFlg (NC.PrintMsg InterestedWindow NIL 
						      "Removing links to and from other cards..."))
						  (for ToLink in ToLinks when (NC.ValidLinkP
										      ToLink)
						     do (NC.DelFromLink ToLink)
							  (NC.DelReferencesToCardFromShowLinks
							    (fetch (Link DestinationCard)
							       of ToLink)
							    ToLink))
						  (for FromLink in FromLinks when (
										    NC.ValidLinkP
											  FromLink)
						     do (NC.DelToLink FromLink)
							  (NC.DelReferencesToCard
							    (fetch (Link SourceCard) of FromLink)
							    Card)
							  (NC.DelReferencesToCardFromShowLinks
							    (fetch (Link SourceCard) of FromLink)
							    FromLink))
						  (OR QuietFlg (NC.PrintMsg InterestedWindow NIL 
										"..done.")))
				       (if (NC.ActiveCardP Card)
					   then (NC.TurnOffDirtyFlgs Card)
						  (SETQ Window (NC.FetchWindow Card))
						  (AND Window (NC.GreyCard Card))
						  (NC.CloseAllPropListEditors Card)
						  (NC.QuitCard Card T T))
				       (NC.ApplyFn MarkCardDeletedFn Card)
				       (NC.SetNewCardFlg Card NIL))
				     (T (NC.CardPartBusy (CAR BusyPart)
							   (CDR BusyPart)
							   InterestedWindow))))))))
)
(* * This function should be deleted from NCLINKS)

(DEFINEQ

(NC.SmartDeleteLinks
  (LAMBDA (ListOfLinks QuietFlg InterestedWindow)            (* Randy.Gobbel " 4-Mar-87 14:40")

          (* * Delete a bunch of links efficiently. Sort so that links with same source bunch together.
	  This way, only read and write each source card once. If a card has the AboutToBeDeletedFlg UID prop set and 
	  Don'tPutToBeDeletedCardsFlg is non-nil, then don't put it down to the file even if changes were made.
	  Just throw away its cache.)



          (* * rht 10/17/86: Now passes non-nil NoOrphanHookFlg to NC.DeleteLink unless destination card is marked as about 
	  to be deleted.)



          (* * rht 11/4/86: Now takes Don'tCreateDeletedImageObjFlg arg.)



          (* * rht 11/13/86: Undid change of 11/4/86. Now passes non-nil Don'tDelLinkIconFlg to NC.DeleteLink instead like it
	  used to.)



          (* * rht 11/14/86: Avoids call to NC.GetNoteCard for cards about to be deleted.)



          (* * rht 12/16/86: Removed obsolete Don'tPutToBeDeletedCardsFlg arg.)


    (LET (DestCardsw/oLinksCached NumLinksToDelete)

          (* * For each destination card, make sure its links are cached. At the same time, collect these cards for future 
	  uncaching.)


         (SETQ DestCardsw/oLinksCached (for Link in ListOfLinks bind DestCard
					    when (NOT (NC.LinksCachedP (SETQ DestCard
									       (fetch (Link 
										  DestinationCard)
										  of Link))))
					    collect (NC.GetLinks DestCard)
						      DestCard))

          (* * Sort the List of links so that links with same source cards bunch together.)


         (OR QuietFlg (NC.PrintMsg InterestedWindow T "Sorting " (SETQ NumLinksToDelete
					 (LENGTH ListOfLinks))
				       " links prior to deletion."))
         (SORT ListOfLinks (FUNCTION (LAMBDA (Link1 Link2)
		     (LESSP (fetch (Card IndexLoc) of (fetch (Link SourceCard) of Link1))
			      (fetch (Card IndexLoc) of (fetch (Link SourceCard) of Link2)))))
		 )

          (* * Now bring up source cards one at a time and do the delete of the links.)


         (OR QuietFlg (NC.PrintMsg InterestedWindow T "Deleting links: 1 out of " 
				       NumLinksToDelete " ..."))
         (for Link in ListOfLinks as i from 1 bind PreviousSourceCard WasNotActiveFlg 
							     SavedFromLinks HadLinksCachedFlg
	    eachtime (BLOCK) when (NC.ValidLinkP Link)
	    do (OR QuietFlg (if (ZEROP (REMAINDER i 10))
				    then (NC.PrintMsg InterestedWindow T "Deleting links: " i 
							  " out of "
							  NumLinksToDelete " ...")))
		 (LET ((SourceCard (fetch (Link SourceCard) of Link)))
		      (if (NOT (NC.SameCardP SourceCard PreviousSourceCard))
			  then                             (* Write down changes to previous card's substance.)
				 (if WasNotActiveFlg
				     then                  (* Have to call NC.CardSaveFn first and then 
							     NC.QuitCard with Don'tSaveFlg to avoid 
							     insureProperFiling check.)
					    (if (NC.UIDGetProp (fetch (Card UID) of 
									       PreviousSourceCard)
								   (QUOTE AboutToBeDeletedFlg))
						then       (* Throw away cache if card about to be deleted.)
						       (NC.DeactivateCard PreviousSourceCard)
					      else (NC.CardSaveFn PreviousSourceCard T)
						     (NC.QuitCard PreviousSourceCard NIL T NIL NIL 
								    NIL T))
                                                             (* Recache links for previous card if they were cached
							     before.)
					    (if HadLinksCachedFlg
						then (NC.GetLinks PreviousSourceCard)))
                                                             (* Cache card and overwrite from links with previously
							     cached ones.)
				 (if (AND (SETQ WasNotActiveFlg (NOT (NC.ActiveCardP 
										       SourceCard)))
					      (NOT (NC.UIDGetProp (fetch (Card UID)
									 of SourceCard)
								      (QUOTE AboutToBeDeletedFlg))))
				     then                  (* Save cached from links for this card.)
					    (SETQ SavedFromLinks (if (SETQ HadLinksCachedFlg
									   (NC.LinksCachedP 
										       SourceCard))
								       then (NC.FetchFromLinks
										SourceCard)))
					    (NC.GetNoteCard SourceCard)
					    (if HadLinksCachedFlg
						then (NC.SetFromLinks SourceCard SavedFromLinks)))
			    )
		      (NC.DeleteLink Link (NC.UIDGetProp (fetch (Card UID)
								of (fetch (Link DestinationCard)
									of Link))
							     (QUOTE AboutToBeDeletedFlg))
				       (NC.UIDGetProp (fetch (Card UID)
							   of (fetch (Link SourceCard)
								   of Link))
							(QUOTE AboutToBeDeletedFlg)))
		      (SETQ PreviousSourceCard SourceCard))
	    finally (if (AND WasNotActiveFlg (NC.ValidCardP PreviousSourceCard))
			  then                             (* Have to call NC.CardSaveFn first and then 
							     NC.QuitCard with Don'tSaveFlg to avoid 
							     insureProperFiling check.)
				 (if (NC.UIDGetProp (fetch (Card UID) of PreviousSourceCard)
							(QUOTE AboutToBeDeletedFlg))
				     then                  (* Throw away cache if card about to be deleted.)
					    (NC.DeactivateCard PreviousSourceCard)
				   else (NC.CardSaveFn PreviousSourceCard T)
					  (NC.QuitCard PreviousSourceCard NIL T NIL NIL NIL T))
                                                             (* Recache links for previous card if they were cached
							     before.)
				 (if HadLinksCachedFlg
				     then (NC.GetLinks PreviousSourceCard))))

          (* * Finally, write down links for cards whose links have changed and whose links weren't cached when this function
	  was called.)


         (for DestCard in DestCardsw/oLinksCached eachtime (BLOCK) when (
									    NC.FetchLinksDirtyFlg
										    DestCard)
	    do (NC.PutLinks DestCard))
         (OR QuietFlg (NC.ClearMsg InterestedWindow T)))))
)
(* * New functions for NCLINKS)

(DEFINEQ

(NC.DeleteFromLink
  (LAMBDA (Link NoOrphanHookFlg)                             (* rht: "13-Mar-87 16:40")

          (* * This is part of what used to be the innards of NC.DeleteLink.)


    (AND (NC.ValidLinkP Link)
	   (LET ((DestinationCard (fetch (Link DestinationCard) of Link)))
	        (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of DestinationCard))
			      (NC.DelFromLink Link NoOrphanHookFlg)
			      (NC.DelReferencesToCardFromShowLinks DestinationCard Link)

          (* * Delete cross file link cards when their links are deleted.)


			      (if (NC.CrossFileLinkCardP DestinationCard)
				  then (NC.DeleteNoteCardInternal DestinationCard)))))))

(NC.DeleteToLink
  (LAMBDA (Link Don'tDelLinkIconFlg)                         (* rht: "13-Mar-87 16:39")

          (* * This is part of what used to be the innards of NC.DeleteLink.)


    (AND (NC.ValidLinkP Link)
	   (LET ((SourceCard (fetch (Link SourceCard) of Link)))
	        (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of SourceCard))
			      (OR Don'tDelLinkIconFlg (NC.DelReferencesToCard SourceCard Link))
			      (NC.DelToLink Link)
			      (NC.DelReferencesToCardFromShowLinks SourceCard Link)

          (* * Delete cross file link cards when their links are deleted.)


			      (if (NC.CrossFileLinkCardP SourceCard)
				  then (NC.DeleteNoteCardInternal SourceCard)))))))
)
(* * Changes to NCLINKS)

(DEFINEQ

(NC.DeleteLink
  (LAMBDA (Link NoOrphanHookFlg Don'tDelLinkIconFlg)         (* rht: "13-Mar-87 16:39")

          (* * Delete a link with the option of not putting an orphan hook in case of last filing link.
	  Also option of not deleting link icon from the source card's substance.)



          (* * fgh 5/2/86 Included calls to NC.DelReferencesToCardFromShowLinks in order to clean up ShowLinks windows when 
	  links are deleted.)



          (* * kef 7/17/86: Added the requirement that the write permissions be obtained for the TOLINKS of the Source Card 
	  and the FROMLINKS of the Destination Card.)



          (* * kef 7/22/86: Puts the links for the Destination Card now right away while we are still holding onto the write 
	  lock for the FROMLINKS.)



          (* * kef 7/30/86: Modified to check for Client's concept of whether he owns the write lock or not, thus deciding 
	  whether or not to setup the release of the write lock afterwards.)



          (* * fgh 8/30/86 Adpated to use NC.IfCardPartNotBusy. Note use of ERROR!. Unfortunately, it appears that the only 
	  way to keep TEDIT from deleting the Link's Image Object is to bail out but good. The control structure here works 
	  because NC.IfCardPartNotBusy returns NIL if the CardPart is busy. The Ts at the end as the last SExpr in each call 
	  to NC.IfCardPartNotBusy insure that NC.IfCardPartNotBusy returns non-NIL otherwise.)



          (* * rht 9/29/86: Removed the call to NC.PutFromLinks. Looks to me like it'll get called anyway by NC.DelFromLink 
	  if necessary.)



          (* * rht 10/6/86: Delete crossfilelink cards when their links are deleted.)



          (* * rht 11/4/86: Now takes Don'tCreateDeletedImageObjFlg arg.)



          (* * rht 11/13/86: Undid my change of 11/4/86.)



          (* * rg 3/11/87 changed call of NC.DeleteNoteCard to NC.DeleteNoteCardInternal)



          (* * rht 3/13/87: Broke out code into the NC.DeleteFromLink and NC.DeleteToLink functions.)


    (AND (NC.ValidLinkP Link)
	   (LET ((SourceCard (fetch (Link SourceCard) of Link))
		 (DestinationCard (fetch (Link DestinationCard) of Link)))
	        (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of SourceCard))
			      (OR (NC.IfCardPartNotBusy DestinationCard (QUOTE FROMLINKS)
							  (OR (NC.IfCardPartNotBusy
								  DestinationCard
								  (QUOTE TOLINKS)
								  (NC.DeleteFromLink Link 
										  NoOrphanHookFlg)
								  (NC.DeleteToLink Link 
									      Don'tDelLinkIconFlg)
								  (replace (Link UID) of Link
								     with -1)
								  T)
								(ERROR!))
							  T)
				    (ERROR!)))))))
)
(* * Changes to NCDATABASE)

(DEFINEQ

(NC.GetLinks
  (LAMBDA (Card OverrideStream)                              (* rht: "13-Mar-87 17:06")

          (* * rht 1/31/85: Now reads pointers from index array.)



          (* * rht 2/9/85: Now fixes display formats on links read in.)



          (* * rht 7/9/85: Now gets date if notefile has newer data format.)



          (* * fkr 11/8/85 Updated to handle new Card scheme and NoteFile objects.)



          (* * fgh 11/20/85 Added call to NC.ReadCardPartHeader)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)



          (* * rht 1/28/86: Now passes extra arg to NC.ReadCardPartHeader indicating that when we're overriding the notefile 
	  stream, you shouldn't force UIDs on stream and in card to match.)



          (* * kef 7/16/86: Uses the device vector GetCardPartFn to set up the stream and stream pointer for reading.)



          (* * kef 8/1/86: Moved the check for ACTIVE status to beginning.)



          (* * fgh 8/31/86 Adapted to use NC.DoCardPartFn.)



          (* * pmi 11/4/86 Reinstated Randy's changes (1/23/86 and 1/28/86) which somehow got lost.)



          (* * rht 3/13/87: No longer goes to notefile if card hasn't been saved yet.)


    (DECLARE (GLOBALVARS NC.LinksIdentifier))
    (if (AND (EQ (fetch (Card Status) of Card)
		       (QUOTE ACTIVE))
		 (NOT (NC.FetchNewCardFlg Card)))
	then (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
			     (NC.DoCardPartFn Get Card (QUOTE LINKS)
					      (LET ((Stream (OR (STREAMP OverrideStream)
								  (NC.CoerceToNoteFileStream Card)))
						    )

          (* * Read the header and set the date)


					           (NC.SetLinksDate Card
								      (NC.ReadCardPartHeader Card 
									       NC.LinksIdentifier 
											   Stream 
										   OverrideStream))

          (* * Read the links)


					           (NC.SetToLinks Card (NC.ReadListOfLinks Stream)
								    )
					           (NC.SetFromLinks Card (NC.ReadListOfLinks
									Stream))
					           (NC.SetGlobalLinks Card (NC.ReadListOfLinks
									  Stream))
					           (NC.SetLinksDirtyFlg Card NIL)
					       Card))))))

(NC.GetPropList
  (LAMBDA (Card OverrideStream)                              (* rht: "13-Mar-87 17:03")
                                                             (* Retrieve the prop list for card specified by ID 
							     from the database specified by DatabaseStream)

          (* * rht 1/31/85: Now reads pointers from index array rather than file.)



          (* * rht 7/9/85: Now gets date if notefile has newer data format.)



          (* * rht 11/10/85 Updated to handle new Card scheme and NoteFile objects.)



          (* * fgh 11/20/85 Added call to NC.ReadCardPartHeader)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)



          (* * rht 1/28/86: Now passes extra arg to NC.ReadCardPartHeader indicating that when we're overriding the notefile 
	  stream, you shouldn't force UIDs on stream and in card to match.)



          (* * kef 7/16/86: Uses the device vector GetCardPartFn to set up the stream and stream pointer for reading.)



          (* * kef 8/1/86: Moved the check for ACTIVE status to beginning.)



          (* * fgh 8/31/86 Adapted to use NC.DoCardPartFn.)



          (* * pmi 11/4/86 Reinstated Randy's changes (1/23/86 and 1/28/86) which somehow got lost.)



          (* * rht 3/13/87: No longer goes to notefile if card hasn't been saved yet.)


    (DECLARE (GLOBALVARS NC.PropsIdentifier))
    (if (AND (EQ (fetch (Card Status) of Card)
		       (QUOTE ACTIVE))
		 (NOT (NC.FetchNewCardFlg Card)))
	then (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
			     (NC.DoCardPartFn Get Card (QUOTE PROPLIST)
					      (LET ((Stream (OR (STREAMP OverrideStream)
								  (NC.CoerceToNoteFileStream Card)))
						    Props)

          (* * set the fileptr to the beginning of the data, read the header, then read the prop list)


					           (NC.SetPropListDate Card
									 (NC.ReadCardPartHeader
									   Card NC.PropsIdentifier 
									   Stream OverrideStream))
					           (NC.SetPropList Card (SETQ Props (
									 NC.ReadPropList Stream)))
					       Props))))))

(NC.GetMainCardData
  (LAMBDA (Card OverrideStream)                              (* rht: "13-Mar-87 17:03")

          (* Get a note card from the database. If IncludeDeletedCardsFlg is NIL, then return immediately if card is deleted 
	  or free. Otherwise, get dekleted but not free cards.)



          (* * rht 1/31/85: Now reads pointers from index array rather than file.)



          (* * rht 7/9/85: Now gets date if notefile has newer data format.)



          (* * rht 11/10/85 Updated to handle new Card scheme and NoteFile objects.)



          (* * fgh 11/20/85 Added call to NC.ReadCardPartHeader and put in code to read Start and End pointers before calling
	  card type's getfn.)



          (* * kirk 27Nov85 abstracted this function out of NC.GetNoteCard)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)



          (* * rht 1/28/86: Now passes extra arg to NC.ReadCardPartHeader indicating that when we're overriding the notefile 
	  stream, you shouldn't force UIDs on stream and in card to match.)



          (* * fgh 2/5/86 Added call to NC.ApplyFn)



          (* * fgh 2/6/86 Added support for version numbers on the substance get fn.)



          (* * kirk 14Feb86 Merged the above 4 changes)



          (* * kef 7/16/86: Uses the device vector GetCardPartFn to set up the stream and stream pointer for reading.)



          (* * kef 8/1/86: Moved the check for ACTIVE status to beginning.)



          (* * fgh 8/31/86 Adpated to use NC.DoCardPartFn.)



          (* * pmi 11/4/86 Reinstated Randy's changes (1/23/86 and 1/28/86) which somehow got lost.)



          (* * rht 3/13/87: No longer goes to notefile if card hasn't been saved yet.)


    (DECLARE (GLOBALVARS NC.ItemIdentifier))
    (if (AND (EQ (fetch (Card Status) of Card)
		       (QUOTE ACTIVE))
		 (NOT (NC.FetchNewCardFlg Card)))
	then (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
			     (NC.DoCardPartFn Get Card (QUOTE SUBSTANCE)
					      (LET ((Stream (OR (STREAMP OverrideStream)
								  (NC.CoerceToNoteFileStream Card)))
						    Length SubstanceVersion)

          (* * Read the header info)


					           (NC.SetItemDate Card (NC.ReadCardPartHeader
								       Card NC.ItemIdentifier Stream 
								       OverrideStream))

          (* * read card type and region)


					           (NC.SetType Card (NC.ReadCardType Stream))
					           (NC.SetRegion Card (NC.ReadRegion Stream))

          (* * Read the length of substance, then call the substance get fn)


					           (SETQ Length (NC.ReadPtr Stream 3))
					           (SETQ SubstanceVersion (NC.GetPtr Stream 1))
					           (NC.SetSubstance Card
								      (NC.ApplyFn GetFn Card Length 
										  Stream 
										 SubstanceVersion))
					       Card))))))

(NC.GetTitle
  (LAMBDA (Card OverrideStream)                              (* rht: "13-Mar-87 17:06")
                                                             (* Retrieve title for card specified by Card from the 
							     database specified by DatabaseStream)

          (* * rht 1/31/85: Now reads pointers from index array rather than file.)



          (* * rht 7/9/85: Now gets date if notefile has newer data format.)



          (* * kirk 10/28/85 Now returns NIL if Status not ACTIVE)



          (* * fkr 10/29/85: Fixed to use new numeric ID format.)



          (* * rht 11/10/85 Updated to handle new Card scheme and NoteFile objects.)



          (* * fgh 11/20/85 Added call to NC.ReadCardPartHeader)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)



          (* * rht 1/28/86: Now passes extra arg to NC.ReadCardPartHeader indicating that when we're overriding the notefile 
	  stream, you shouldn't force UIDs on stream and in card to match.)



          (* * kef 7/16/86: Uses the device vector GetCardPartFn to set the stream and stream pointer in preparation for the 
	  read.)



          (* * kef 7/24/86: Added check of NewCardFlg.)



          (* * fgh 8/31/86 Adtaped to use NC.DoCardPartFn.)



          (* * pmi 11/4/86 Reinstated Randy's changes (1/23/86 and 1/28/86) which somehow got lost.)



          (* * rht 3/13/87: No longer goes to notefile if card hasn't been saved yet.)


    (DECLARE (GLOBALVARS NC.TitlesIdentifier))
    (if (AND (EQ (fetch (Card Status) of Card)
		       (QUOTE ACTIVE))
		 (NOT (fetch (Card NewCardFlg) of Card)))
	then (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
			     (NC.DoCardPartFn Get Card (QUOTE TITLE)

          (* * Now we've actually executed the BEFORE part of the GETFN, while in a RESETLST that will ensure execution of 
	  the AFTER part upon exit. This means that right now the Stream slot of the NoteFile is a random access stream with 
	  the file pointer set to the beginning of the card part.)


					      (LET ((Stream (OR (STREAMP OverrideStream)
								  (NC.CoerceToNoteFileStream Card)))
						    Title)
					           (NC.SetTitleDate Card
								      (NC.ReadCardPartHeader Card 
									      NC.TitlesIdentifier 
											   Stream 
										   OverrideStream))
					           (NC.SetTitle Card (SETQ Title (NC.ReadTitle
								      Stream)))
					       Title))))))
)
(* * Changes to NCCOMPACT)

(FILESLOAD (FROM NOTECARDS)
	   NCCOMPACT)
(DEFINEQ

(NC.CompactNoteFileToTarget
  (LAMBDA (FromNoteFile ToFileName InterestedWindow)         (* rht: "13-Mar-87 17:48")

          (* * In sorted order, copy card parts to lower addresses in the file.)



          (* * fgh 5/1/86 Now returns the ToNoteFile in order to be compatible with compact in place.)



          (* * rht 11/3/86: Now opens FromNoteFile read-only. Also now takes InterestedWindow arg.)



          (* * rht 1/22/87: Slight change to computation of new index size.)


    (LET (FromFileLength ToNoteFile TargetStream TargetFileLength OriginalStream BytesRecovered 
			 OperationMsg)
         (SETQ FromNoteFile
	   (NC.OpenNoteFile FromNoteFile NIL T T T NIL T T T InterestedWindow NIL NIL NIL T))
         (SETQ OperationMsg (CONCAT "Compacting " (fetch (NoteFile FullFileName) of 
										     FromNoteFile)
					(CHARACTER 13)))
         (SETQ ToNoteFile (NC.OpenDatabaseFile (NC.CreateDatabaseFile
						     ToFileName
						     (OR (NC.ComputeNewDatabaseIndexSize 
										     FromNoteFile)
							   (fetch (NoteFile HashArraySize)
							      of FromNoteFile))
						     OperationMsg T NIL T InterestedWindow)
						   NIL T NIL T T T T T T InterestedWindow))
         (SETQ TargetStream (fetch (NoteFile Stream) of ToNoteFile))
         (SETQ OriginalStream (fetch (NoteFile Stream) of FromNoteFile))
         (replace (NoteFile NextIndexNum) of ToNoteFile with (fetch (NoteFile NextIndexNum)
								      of FromNoteFile))
         (SETFILEPTR TargetStream (NC.TotalIndexSize (fetch (NoteFile HashArraySize)
							    of ToNoteFile)))
                                                             (* truncate ToNoteFile after the index)
         (if (NC.CopySortedCardParts (NC.SortIndexEntries FromNoteFile)
					 ToNoteFile NIL NIL NIL InterestedWindow OperationMsg)
	     then                                          (* all useable card parts got copied)
		    (SETQ FromFileLength (GETEOFPTR OriginalStream)) 

          (* * fool NC.PutHashArray into writing out the index for the new NoteFile)


		    (replace (NoteFile Stream) of FromNoteFile with TargetStream)
		    (NCLocalDevice.PutHashArray FromNoteFile InterestedWindow T OperationMsg)
		    (replace (NoteFile Stream) of FromNoteFile with OriginalStream) 

          (* * Put out the new ChkptPtr to the file.)


		    (replace (NoteFile CheckptPtr) of ToNoteFile with (SETQ TargetFileLength
									      (GETEOFPTR 
										     TargetStream)))

          (* * Steal the UID from the original file so links will work. Write out the header.)


		    (replace (NoteFile UID) of ToNoteFile with (fetch (NoteFile UID)
									of FromNoteFile))
		    (NC.PutNoteFileHeader ToNoteFile)
		    (SETQ BytesRecovered (DIFFERENCE FromFileLength TargetFileLength))
		    (NC.PrintMsg NIL T (fetch (NoteFile FullFileName) of FromNoteFile)
				   " compacted to "
				   (fetch (NoteFile FullFileName) of ToNoteFile)
				   (CHARACTER 13)
				   "Recovered " BytesRecovered " bytes ("
				   (FIX (TIMES 100 (FQUOTIENT BytesRecovered FromFileLength)))
				   "%%)"
				   (CHARACTER 13))
		    (NC.ClearMsg InterestedWindow T))
         (NC.ForceDatabaseClose FromNoteFile T)
         (SETQ ToNoteFile (NC.ForceDatabaseClose ToNoteFile T))
     ToNoteFile)))

(NC.CompactNoteFileInPlace
  (LAMBDA (NoteFile InterestedWindow)                        (* rht: "13-Mar-87 17:55")

          (* * Compact the notefile in place. If index needs to be increased, then first make room for bigger index by 
	  copying. Compaction is done by sorting index pointers and moving each entry in the file to lower addresses.)



          (* * fkr 11/8/85 Updated to handle new CardID scheme and NoteFile object.)



          (* * kirk 19Nov85: Created from NC.CompactDatabaseInPlace)



          (* * rht 11/3/86: Added InterestedWindow arg.)



          (* * rht&pmi 12/9/86: Moved RESETLST to be after call to NC.OpenDatabaseFile.)



          (* * rht 1/22/87: Now bails out if NC.ExpandIndexInPlace was called but returned NIL. Also fixed message when size 
	  of notefile actually increases.)


    (if (AND NoteFile (SETQ NoteFile (NC.OpenNoteFile NoteFile NIL T T NIL NIL T T T 
							      InterestedWindow)))
	then (RESETLST (RESETSAVE NIL (BQUOTE (NC.ForceDatabaseClose , NoteFile)))
			   (LET ((SourceStream (fetch (NoteFile Stream) of NoteFile))
				 (BufferStream (OPENSTREAM (QUOTE {NODIRCORE})
							     (QUOTE BOTH)
							     NIL
							     (QUOTE ((TYPE BINARY)))))
				 (FullFileName (fetch (NoteFile FullFileName) of NoteFile))
				 (NewIndexSize (NC.ComputeNewDatabaseIndexSize NoteFile))
				 ToPtr OriginalLengthOfFile OperationMsg)

          (* * Expand index if needed.)


			        (SETQ OperationMsg (CONCAT "Compacting " FullFileName 
							       " in place."
							       (CHARACTER 13)))
			        (SETQ OriginalLengthOfFile (GETEOFPTR SourceStream))

          (* * In sorted order, copy entries to lower locations in the file. Expand index first if necessary.)


			        (if (AND (OR (NULL NewIndexSize)
						   (NC.ExpandIndexInPlace NoteFile NewIndexSize 
									    BufferStream 
									    InterestedWindow 
									    OperationMsg))
					     (SETQ ToPtr (NC.CopySortedCardParts
						 (NC.SortIndexEntries NoteFile)
						 NIL
						 (NC.TotalIndexSize (fetch (NoteFile 
										    HashArraySize)
									 of NoteFile))
						 BufferStream
						 (GETEOFPTR SourceStream)
						 InterestedWindow OperationMsg)))
				    then                   (* all useable card parts got copied)
					   (NC.PutCheckptPtr NoteFile ToPtr) 
                                                             (* Put out the new ChkptPtr to the file.)

          (* * Truncate file at that point.)


					   (NC.PrintMsg InterestedWindow T "Truncating file " 
							  FullFileName " ...")
					   (NCLocalDevice.PutHashArray NoteFile InterestedWindow T 
									 OperationMsg)
					   (if (NOT (SETFILEINFO FullFileName (QUOTE LENGTH)
								       ToPtr))
					       then (NC.PrintMsg InterestedWindow NIL 
								     "Couldn't truncate "
								     FullFileName "." (CHARACTER
								       13))
					     else (NC.PrintMsg InterestedWindow T "Done."
								   (CHARACTER 13))
						    (NC.ClearMsg InterestedWindow T))
					   (LET ((NumBytesSaved (DIFFERENCE OriginalLengthOfFile 
									      ToPtr)))
					        (if (MINUSP NumBytesSaved)
						    then (NC.PrintMsg
							     NIL T FullFileName 
							     " compacted in place."
							     (CHARACTER 13)
							     "Increased by "
							     (MINUS NumBytesSaved)
							     " bytes ("
							     (FIX (TIMES 100 (FQUOTIENT
									       (MINUS NumBytesSaved)
									       OriginalLengthOfFile)))
							     "%%)"
							     (CHARACTER 13))
						  else (NC.PrintMsg NIL T FullFileName 
									" compacted in place."
									(CHARACTER 13)
									"Recovered " NumBytesSaved 
									" bytes ("
									(FIX (TIMES 100
											(FQUOTIENT
											  
										    NumBytesSaved 
									     OriginalLengthOfFile)))
									"%%)"
									(CHARACTER 13))))
					   (SETQ NC.DatabaseFileNameSuggestion (PACKFILENAME
					       (QUOTE VERSION)
					       NIL
					       (QUOTE BODY)
					       FullFileName))
				  else (FLASHW PROMPTWINDOW)
					 (NC.PrintMsg NIL T "Compact of " FullFileName 
							" cancelled.")))))))
)
(PUTPROPS RHTPATCH215 COPYRIGHT ("Xerox Corporation" 1987))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (1649 3229 (NC.SeverAllLinks 1659 . 3227)) (3267 8883 (NC.SeverExternalLinks 3277 . 8881
)) (8915 20638 (NC.DeleteNoteCards 8925 . 14722) (NC.DeleteNoteCardInternal 14724 . 20636)) (20696 
27133 (NC.SmartDeleteLinks 20706 . 27131)) (27172 28707 (NC.DeleteFromLink 27182 . 27926) (
NC.DeleteToLink 27928 . 28705)) (28739 31554 (NC.DeleteLink 28749 . 31552)) (31589 42012 (NC.GetLinks 
31599 . 33976) (NC.GetPropList 33978 . 36274) (NC.GetMainCardData 36276 . 39340) (NC.GetTitle 39342 . 
42010)) (42089 50135 (NC.CompactNoteFileToTarget 42099 . 45675) (NC.CompactNoteFileInPlace 45677 . 
50133)))))
STOP