ChangeLog for MoLib by MooreaTv (moorea@ymail.com)
--------------------------------------------------
Extensively used by DynamicBoxer e.g.
https://github.com/mooreatv/DynamicBoxer/blob/master/DynamicBoxer/DBoxUI.lua 
but also meant to be reused in other addons, not just mine.

v7.03.04 July 28th 2019
- Fix for "..." of strings at some scale and removed need for double snap
  also avoids shimmering when stop scaling (for DynamicBoxer status frame)
v7.03.03 July 28th 2019
- added :SetClampedToScreen(true) (Issue #11)
- Workaround/Fix for https://github.com/mooreatv/DynamicBoxer/issues/65
- Handle right aligned text better using 2 snap and the fontstring un wrapped width
- added :SetTopLeft and use it to Fix https://github.com/mooreatv/DynamicBoxer/issues/64
  by forcing TOPLEFT anchor for save/restore (as the widgets grow right and down, not up)

v7.03.02 July 25th 2019 (matches ppa v1.04.00)
- Added :GetCursorCoordinates() returning (pixelX, pixelY, uicoordX, uicoordY) for the cursor
v7.03.01 July 25th 2019 (matches dbox v2.01.00)
- Moved more code from DynamicBoxer to share with (my and other's) addons:
    - new :MakeMoveable() to add dragging to a frame, with callback at the end to :SavePosition()
    - new :RestorePosition() to call with what is saved by the MakeMoveable cb and SavePosition()
    - use new :PixelPerfectSnap() for :Snap()
- roundUp() works for negative numbers too (like point offsets from the top)
- Opsa fixed collision between "first" as init marker and the new :first() lisp function
- Also fixed handling of UI_SCALED_CHANGED broken recently for UIParent based Pixel Perfect base frames.
- added :DrawPixel and use that for 1 pixel crosses instead of 2 lines (!)
- addBorder remembers the lines made in f.border and the desired pixel thickness and adjusts on rescale to keep it
- addLine option, used by addBorder to not add the line to the handled children of the frame

v7.02.00 July 22nd 2019
- Beat the 16k limit (well 16k at a time) for Textures/Lines count (use :Demo() to see and MoLib_PP_Demo:Hide()/Show() to toggle)
- Expose grid demo colors .gold/.red
- minimap button/icon/launcher, allow to restore saved position
- moved :ShowToolTip() and :SplitFullName() from DynamicBoxer (to use in PPA/by others)
- new lisp like function :first() (car ...) :rest() (cdr ...) and :Map(fn, ...) to apply a function to each remaining argument.
v7.01.00 July 21st 2019
- Allow single pixel for grid with length == 1 in :FineGrid()
- :PixelPerfectScale() to update scale on PP frames and using it on change screen/scale events
- :AspectRatio() calc and showing in DisplayInfo, always show a center cross even for even aspect ratios
- added .defaultFont and .defaultTextColor properties to Frame() used by .addText()
- :GetCVar for classic/bfa compat

v7.00.01 July 21st 2019
- Fix for modification for center cross (grid demo) was changing the whole line after it
v7.00.00 July 21st 2019
- Pixel perfect for real now - See PixelPerfectAlign demo addon
  :FineGrid() and :DisplayInfo()
- new :addLine() :addBorder() :WipeFrame()

v6.00.02 July 20th 2019
- added :DebugStack(...) that prints message and stack trace
v6.00.01 July 18th 2019
- add optional points for PlaceLeft/PlaceRight (so DynamicBoxer can use centered points)
v6.00.00 July 17th 2019
- Move in code from DynamicBoxer :ChangeScale  f:addTexture
- added comments/doc
- new :PreloadTextures (pending using coroutine/continuations or delaying layout 
  on update event for textures that aren't loaded yet)
- overridePadding argument in (set)Scale() and better calculation of scale.
- new :addAnimatedTexture
- new :PlaceLeft() meant to place a single item to the left of last right
- RgbToHex takes optional 4th argument for alpha

5.3.2 July 15th 2019
- Fixed slider to show formatted decimal numbers
- Add optional call back (.callBack) to sliders
5.3.1 July 11th 2019
- fixed RgbToHex, was missing leading 0s on small hex numbers. also use uppercase.
- widget addText can take either a font name string or a font object as 2nd param.
- Adding a :Scale() that use the current frame anchor and scale the inside to fit
  (kind of reverse of Snap() which changes the size of container to fit content)
- Made Place() take optional Points so one can do centered layout (see DynamicBoxer TAB feature)
5.3.0 July 11th 2019
- pixel perfect snap to pixel boundary with :SnapFrame() on any frame
- proper bottom right margin calculation and setting in f:Snap() 
- new :ErrorAndThrow(...) to both log a formatted error and throw the same message
- working (for players as target) :GetUnitRealmUsingGuid() and :GetRealRealm()
  (first uses just the guid's realmid, second uses the playerinfobyguid)
5.2.1 July 9th+ 2019
- new: :WatchedTable() a table where you get a callback when values are changed.
- MoLibUI: added :setSizeToChildren which calculates the bounding box union of all placed children and
sets that as the width and height of the containing frame.
- new :RgbToHex
5.2.0 July 7th 2019
- (start of) Localization support: ML:GetLocalization creates an L table compatible with
https://authors.curseforge.com/knowledge-base/world-of-warcraft/531-localization-substitutions
- default DoEnable/DoDisable on all widgets
5.1.1 July 6th 2019
- Fixing taint by delaying creation of widget (see DynamicBoxer#38 and use/fix)
5.1.0 July 4th 2019
- Adding Realms.lua realm by id table obtained from Blizzard APIs with
  https://github.com/mooreatv/WowApiClient
5.0.0 July 3rd 2019
- MoLibUI: Moved code from DynamicBoxer DBoxUI.lua so it can be reused
(see example of use at the end of
 https://github.com/mooreatv/DynamicBoxer/blob/master/DynamicBoxer/DBoxUI.lua)

On going updates from June 7th-30th 2019
4.1.0
- Incompatible change:
VerifySecureMessage returns true or false as first argument and an error message as
second argument instead of printing their own Warning
- adding :CloneTable as convenience shortcut deepmerge into a new table, also handles nicely nil and non table source
  and will always return a table
- adding :PrintDefault and :PrintInfo for white and blue printing with format'ing
- colors tweak
4.0.0
- ***Big incompatible change!*** all functions now declared with ":" and not a mix and match of "." and ":"
check all the callers, always use ":" !
- added LRU:exists() and :newest() (and earlier :fromTable(table) and :toTable())
- adding .Factions list of possible values returned by UnitFactionGroup()
- fix ML.name use instead of self.name use in debug print
- :Debug now shows SS.XX prefix where SS is modulo 100 seconds and XX hundredth of seconds
- added LRU:toTable() and LRU:fromTable() and optional table argument to constructor (ML:LRU()) to import/export to flat table
- ML.secureFutureThreshold = -5 ML.securePastThreshold = 45 changeable defaults instead of hardcoded -5 and +15 seconds before
- Switched hashing to be 64 bits (2x32bits to be precise), :Sign and :CreateSecureMessage uses the 64bits hex string
- new :ToHex(n) that gives a 32 bit (8 characters long) hex string representation (lua's %x fails for 2-4B)
- CreateSecureMessage and VerifySecureMessage both now return the signature to be used as messageId
- Dump/Debug etc now properly escape the wow | sequences
- new .StartsWith(str, prefix [, cb]) returns true and the reminder of the str if str starts with prefix,
optional cb argument is called with reminder of str after prefix if a match is found.
- new :CreateSecureMessage and :VerifySecureMessage functions to exchange time limited secure messages 
based on 1 visible and 1 secret token, embeds server time and checks it too (messages stay valid for 15s)
- new :Sign(msg, secret) which returns the long hash of msg .. secret, also exposed .Hash() in addition
to earlier .ShortHash()
- new ML.LRU(capacity) instance constructor with :add() and :iterateNewest() and :iterateOldest() methods
- the Dump function (and thus Debug, etc...) can now print structures with pointer without infinite loop
- start of some tests in tests/ directory, and reduced reliance on wow specific functions to limit the number of shm needed
- changed all functions using :Debug to be :Functions (take self arg)
	so the debugging level of user addons embedded under different
	namespace do work (RandomId)
- new :AddHashKey to add a single alphanum character hash at the end of a string
- new :UnHash to check validity of, and remove previous hash key
- new :GsubEsc(str) escapes a string so it can be used literally
as a string.gsub(haystack, needle, replace) needle (ie escapes %?*-...)
- new :ReplaceAll(haystack, needle, replace, ...) replaces literally
every occurrence of needle by replace in haystack, rest of signature
and return is same as gsub()
- new :ShortHash(str) returning 1 alpha num hash of input string (and
the longer 32 bits hash numerical value)
- changed DebugEvCall to take mandatory level arg 
- new :RandomId(len) for random alpha num string of length len
- new :Warning(formatStr, ...) for warnings with nice orange color
- :Debug now takes optional level first argument (if absent level is 1), use higher level
	for more verbose levels
- new :Error(formatStr, ...) for errors in red function
- Format() and thus Debug() now Dump()s table arguments
- GetMyFQN when called to early can fail (for instance at UPDATE_BINDINGS time the realm is nil(!))
- Darker green for :Debug() to not confuse with guild chat

3.1.0 June 6th 2019
- MoLib can now be installed in a different namespace than the one of the addon's name
use MoLibInstallInto(namespace, name) to do so
- As a consequence Debug() and MoLibInit() must be called using : so they can access state
- Adding multi valued Dump(...)
- Adding debug Ev handler DebugEvCall
- prefix seconds (server time) prefix to debug logging
- adding GetMyFQN fully qualified characterName-normalizedRealm
3.0.0 June 6th 2019
- Created MoLib for common code between WhoTracker, Camera, DynamicBoxer etc

[... rest of the changelog in WhoTracker: https://github.com/mooreatv/WhoTracker ]

1.0.0	Feb 20th 2009
- Initial Release
