{"version":3,"sources":["_layouts/core/utils/webtoolkit.base64.js","_layouts/core/utils/md5.js","_layouts/core/utils/session.js","_layouts/core/utils/functions.js","_layouts/core/utils/notifications.js","_layouts/core/utils/librarian.utils.js","_layouts/core/utils/login.sso.js","_layouts/core/utils/login.js","_layouts/core/config/librarian.config.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/PA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrmIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzlBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"_layouts/core/utils/login.bundle.js","sourcesContent":["/**\r\n*\r\n* Base64 encode / decode\r\n* http://www.webtoolkit.info/\r\n*\r\n**/\r\n\r\nvar Base64 = {\r\n // private property\r\n _keyStr: \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\",\r\n\r\n // public method for encoding\r\n encode: function(input) {\r\n var chr1, chr2, chr3, enc1, enc2, enc3, enc4,\r\n i = 0,\r\n buf = new StringBuffer();\r\n\r\n input = Base64._utf8_encode(input);\r\n while (i < input.length) {\r\n chr1 = input.charCodeAt(i++);\r\n chr2 = input.charCodeAt(i++);\r\n chr3 = input.charCodeAt(i++);\r\n\r\n enc1 = chr1 >> 2;\r\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\r\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\r\n enc4 = chr3 & 63;\r\n\r\n if (isNaN(chr2))\r\n enc3 = enc4 = 64;\r\n else if (isNaN(chr3))\r\n enc4 = 64;\r\n\r\n buf.append(this._keyStr.charAt(enc1));\r\n buf.append(this._keyStr.charAt(enc2));\r\n buf.append(this._keyStr.charAt(enc3));\r\n buf.append(this._keyStr.charAt(enc4));\r\n }\r\n\r\n return buf.toString();\r\n },\r\n\r\n // public method for decoding\r\n decode: function(input) {\r\n var chr1, chr2, chr3,\r\n enc1, enc2, enc3, enc4,\r\n i = 0,\r\n buf = new StringBuffer();\r\n\r\n input = (input + '').replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\r\n\r\n while (i < input.length) {\r\n enc1 = this._keyStr.indexOf(input.charAt(i++));\r\n enc2 = this._keyStr.indexOf(input.charAt(i++));\r\n enc3 = this._keyStr.indexOf(input.charAt(i++));\r\n enc4 = this._keyStr.indexOf(input.charAt(i++));\r\n\r\n chr1 = (enc1 << 2) | (enc2 >> 4);\r\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\r\n chr3 = ((enc3 & 3) << 6) | enc4;\r\n\r\n buf.append(String.fromCharCode(chr1));\r\n\r\n if (enc3 != 64) {\r\n buf.append(String.fromCharCode(chr2));\r\n }\r\n if (enc4 != 64) {\r\n buf.append(String.fromCharCode(chr3));\r\n }\r\n }\r\n\r\n return Base64._utf8_decode(buf.toString());\r\n },\r\n\r\n // private method for UTF-8 encoding\r\n _utf8_encode: function(string) {\r\n string = (string + '').replace(/\\r\\n/g, \"\\n\");\r\n var buf = new StringBuffer();\r\n\r\n for (var n = 0; n < string.length; n++) {\r\n var c = string.charCodeAt(n);\r\n\r\n if (c < 128) {\r\n buf.append(String.fromCharCode(c));\r\n }\r\n else if ((c > 127) && (c < 2048)) {\r\n buf.append(String.fromCharCode((c >> 6) | 192));\r\n buf.append(String.fromCharCode((c & 63) | 128));\r\n }\r\n else {\r\n buf.append(String.fromCharCode((c >> 12) | 224));\r\n buf.append(String.fromCharCode(((c >> 6) & 63) | 128));\r\n buf.append(String.fromCharCode((c & 63) | 128));\r\n }\r\n }\r\n\r\n return buf.toString();\r\n },\r\n\r\n // private method for UTF-8 decoding\r\n _utf8_decode: function(utftext) {\r\n var buf = new StringBuffer(),\r\n i = 0,\r\n c, c1, c2;\r\n\r\n while (i < utftext.length) {\r\n\r\n c = utftext.charCodeAt(i);\r\n\r\n if (c < 128) {\r\n buf.append(String.fromCharCode(c));\r\n i++;\r\n }\r\n else if ((c > 191) && (c < 224)) {\r\n c1 = utftext.charCodeAt(i + 1);\r\n buf.append(String.fromCharCode(((c & 31) << 6) | (c1 & 63)));\r\n i += 2;\r\n }\r\n else {\r\n c1 = utftext.charCodeAt(i + 1);\r\n c2 = utftext.charCodeAt(i + 2);\r\n buf.append(String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63)));\r\n i += 3;\r\n }\r\n }\r\n\r\n return buf.toString();\r\n }\r\n};","\r\n/* Version 4.2.3.001 */\r\n/*\r\n * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\r\n * Digest Algorithm, as defined in RFC 1321.\r\n * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.\r\n * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\r\n * Distributed under the BSD License\r\n * See http://pajhome.org.uk/crypt/md5 for more info.\r\n */\r\n\r\nvar Encrypt = {\r\n /*\r\n * Configurable variables. You may need to tweak these to be compatible with\r\n * the server-side, but the defaults work in most cases.\r\n */\r\n hexcase: 0, /* hex output format. 0 - lowercase; 1 - uppercase */\r\n b64pad: '', /* base-64 pad character. \"=\" for strict RFC compliance */\r\n chrsz: 8, /* bits per input character. 8 - ASCII; 16 - Unicode */\r\n\r\n /*\r\n * These are the functions you'll usually want to call\r\n * They take string arguments and return either hex or base-64 encoded strings\r\n */\r\n hex_md5: function(s) {\r\n return Encrypt.binl2hex(Encrypt.core_md5(Encrypt.str2binl(s), s.length * Encrypt.chrsz));\r\n },\r\n\r\n b64_md5: function(s) {\r\n return Encrypt.binl2b64(Encrypt.core_md5(Encrypt.str2binl(s), s.length * Encrypt.chrsz));\r\n },\r\n\r\n str_md5: function(s) {\r\n return Encrypt.binl2str(Encrypt.core_md5(Encrypt.str2binl(s), s.length * Encrypt.chrsz));\r\n },\r\n\r\n hex_hmac_md5: function(key, data) {\r\n return Encrypt.binl2hex(Encrypt.core_hmac_md5(key, data));\r\n },\r\n\r\n b64_hmac_md5: function(key, data) {\r\n return Encrypt.binl2b64(Encrypt.core_hmac_md5(key, data));\r\n },\r\n\r\n str_hmac_md5: function(key, data) {\r\n return Encrypt.binl2str(Encrypt.core_hmac_md5(key, data));\r\n },\r\n\r\n /* \r\n * Perform a simple self-test to see if the VM is working \r\n */\r\n md5_vm_test: function() {\r\n return Encrypt.hex_md5(\"abc\") == \"900150983cd24fb0d6963f7d28e17f72\";\r\n },\r\n\r\n /*\r\n * Calculate the MD5 of an array of little-endian words, and a bit length\r\n */\r\n core_md5: function(x, len) {\r\n /* append padding */\r\n x[len >> 5] |= 0x80 << ((len) % 32);\r\n x[(((len + 64) >>> 9) << 4) + 14] = len;\r\n\r\n var a = 1732584193;\r\n var b = -271733879;\r\n var c = -1732584194;\r\n var d = 271733878;\r\n\r\n for (var i = 0; i < x.length; i += 16) {\r\n var olda = a;\r\n var oldb = b;\r\n var oldc = c;\r\n var oldd = d;\r\n\r\n a = Encrypt.md5_ff(a, b, c, d, x[i + 0], 7, -680876936);\r\n d = Encrypt.md5_ff(d, a, b, c, x[i + 1], 12, -389564586);\r\n c = Encrypt.md5_ff(c, d, a, b, x[i + 2], 17, 606105819);\r\n b = Encrypt.md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);\r\n a = Encrypt.md5_ff(a, b, c, d, x[i + 4], 7, -176418897);\r\n d = Encrypt.md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);\r\n c = Encrypt.md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);\r\n b = Encrypt.md5_ff(b, c, d, a, x[i + 7], 22, -45705983);\r\n a = Encrypt.md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);\r\n d = Encrypt.md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);\r\n c = Encrypt.md5_ff(c, d, a, b, x[i + 10], 17, -42063);\r\n b = Encrypt.md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);\r\n a = Encrypt.md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);\r\n d = Encrypt.md5_ff(d, a, b, c, x[i + 13], 12, -40341101);\r\n c = Encrypt.md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);\r\n b = Encrypt.md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);\r\n\r\n a = Encrypt.md5_gg(a, b, c, d, x[i + 1], 5, -165796510);\r\n d = Encrypt.md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);\r\n c = Encrypt.md5_gg(c, d, a, b, x[i + 11], 14, 643717713);\r\n b = Encrypt.md5_gg(b, c, d, a, x[i + 0], 20, -373897302);\r\n a = Encrypt.md5_gg(a, b, c, d, x[i + 5], 5, -701558691);\r\n d = Encrypt.md5_gg(d, a, b, c, x[i + 10], 9, 38016083);\r\n c = Encrypt.md5_gg(c, d, a, b, x[i + 15], 14, -660478335);\r\n b = Encrypt.md5_gg(b, c, d, a, x[i + 4], 20, -405537848);\r\n a = Encrypt.md5_gg(a, b, c, d, x[i + 9], 5, 568446438);\r\n d = Encrypt.md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);\r\n c = Encrypt.md5_gg(c, d, a, b, x[i + 3], 14, -187363961);\r\n b = Encrypt.md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);\r\n a = Encrypt.md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);\r\n d = Encrypt.md5_gg(d, a, b, c, x[i + 2], 9, -51403784);\r\n c = Encrypt.md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);\r\n b = Encrypt.md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);\r\n\r\n a = Encrypt.md5_hh(a, b, c, d, x[i + 5], 4, -378558);\r\n d = Encrypt.md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);\r\n c = Encrypt.md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);\r\n b = Encrypt.md5_hh(b, c, d, a, x[i + 14], 23, -35309556);\r\n a = Encrypt.md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);\r\n d = Encrypt.md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);\r\n c = Encrypt.md5_hh(c, d, a, b, x[i + 7], 16, -155497632);\r\n b = Encrypt.md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);\r\n a = Encrypt.md5_hh(a, b, c, d, x[i + 13], 4, 681279174);\r\n d = Encrypt.md5_hh(d, a, b, c, x[i + 0], 11, -358537222);\r\n c = Encrypt.md5_hh(c, d, a, b, x[i + 3], 16, -722521979);\r\n b = Encrypt.md5_hh(b, c, d, a, x[i + 6], 23, 76029189);\r\n a = Encrypt.md5_hh(a, b, c, d, x[i + 9], 4, -640364487);\r\n d = Encrypt.md5_hh(d, a, b, c, x[i + 12], 11, -421815835);\r\n c = Encrypt.md5_hh(c, d, a, b, x[i + 15], 16, 530742520);\r\n b = Encrypt.md5_hh(b, c, d, a, x[i + 2], 23, -995338651);\r\n\r\n a = Encrypt.md5_ii(a, b, c, d, x[i + 0], 6, -198630844);\r\n d = Encrypt.md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);\r\n c = Encrypt.md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);\r\n b = Encrypt.md5_ii(b, c, d, a, x[i + 5], 21, -57434055);\r\n a = Encrypt.md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);\r\n d = Encrypt.md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);\r\n c = Encrypt.md5_ii(c, d, a, b, x[i + 10], 15, -1051523);\r\n b = Encrypt.md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);\r\n a = Encrypt.md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);\r\n d = Encrypt.md5_ii(d, a, b, c, x[i + 15], 10, -30611744);\r\n c = Encrypt.md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);\r\n b = Encrypt.md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);\r\n a = Encrypt.md5_ii(a, b, c, d, x[i + 4], 6, -145523070);\r\n d = Encrypt.md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);\r\n c = Encrypt.md5_ii(c, d, a, b, x[i + 2], 15, 718787259);\r\n b = Encrypt.md5_ii(b, c, d, a, x[i + 9], 21, -343485551);\r\n\r\n a = Encrypt.safe_add(a, olda);\r\n b = Encrypt.safe_add(b, oldb);\r\n c = Encrypt.safe_add(c, oldc);\r\n d = Encrypt.safe_add(d, oldd);\r\n }\r\n return Array(a, b, c, d);\r\n\r\n },\r\n\r\n /*\r\n * These functions implement the four basic operations the algorithm uses.\r\n */\r\n md5_cmn: function(q, a, b, x, s, t) {\r\n return Encrypt.safe_add(Encrypt.bit_rol(Encrypt.safe_add(Encrypt.safe_add(a, q), Encrypt.safe_add(x, t)), s), b);\r\n },\r\n\r\n md5_ff: function (a, b, c, d, x, s, t) {\r\n return Encrypt.md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);\r\n },\r\n\r\n md5_gg: function (a, b, c, d, x, s, t) {\r\n return Encrypt.md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);\r\n },\r\n\r\n md5_hh: function (a, b, c, d, x, s, t) {\r\n return Encrypt.md5_cmn(b ^ c ^ d, a, b, x, s, t);\r\n },\r\n\r\n md5_ii: function (a, b, c, d, x, s, t) {\r\n return Encrypt.md5_cmn(c ^ (b | (~d)), a, b, x, s, t);\r\n },\r\n\r\n /*\r\n * Calculate the HMAC-MD5, of a key and some data\r\n */\r\n core_hmac_md5: function(key, data) {\r\n var bkey = Encrypt.str2binl(key);\r\n if (bkey.length > 16)\r\n bkey = Encrypt.core_md5(bkey, key.length * Encrypt.chrsz);\r\n\r\n var ipad = Array(16), opad = Array(16);\r\n for (var i = 0; i < 16; i++) {\r\n ipad[i] = bkey[i] ^ 0x36363636;\r\n opad[i] = bkey[i] ^ 0x5C5C5C5C;\r\n }\r\n\r\n var hash = Encrypt.core_md5(ipad.concat(Encrypt.str2binl(data)), 512 + data.length * Encrypt.chrsz);\r\n return Encrypt.core_md5(opad.concat(hash), 512 + 128);\r\n },\r\n\r\n /*\r\n * Add integers, wrapping at 2^32. This uses 16-bit operations internally\r\n * to work around bugs in some JS interpreters.\r\n */\r\n safe_add: function(x, y) {\r\n var lsw = (x & 0xFFFF) + (y & 0xFFFF);\r\n var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\r\n return (msw << 16) | (lsw & 0xFFFF);\r\n },\r\n\r\n /*\r\n * Bitwise rotate a 32-bit number to the left.\r\n */\r\n bit_rol: function(num, cnt) {\r\n return (num << cnt) | (num >>> (32 - cnt));\r\n },\r\n\r\n /*\r\n * Convert a string to an array of little-endian words\r\n * If Encrypt.chrsz is ASCII, characters >255 have their hi-byte silently ignored.\r\n */\r\n str2binl: function(str) {\r\n var bin = Array();\r\n var mask = (1 << Encrypt.chrsz) - 1;\r\n for (var i = 0; i < str.length * Encrypt.chrsz; i += Encrypt.chrsz)\r\n bin[i >> 5] |= (str.charCodeAt(i / Encrypt.chrsz) & mask) << (i % 32);\r\n return bin;\r\n },\r\n\r\n /*\r\n * Convert an array of little-endian words to a string\r\n */\r\n binl2str: function(bin) {\r\n var str = \"\";\r\n var mask = (1 << Encrypt.chrsz) - 1;\r\n for (var i = 0; i < bin.length * 32; i += Encrypt.chrsz)\r\n str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask);\r\n return str;\r\n },\r\n\r\n /*\r\n * Convert an array of little-endian words to a hex string.\r\n */\r\n binl2hex: function(binarray) {\r\n var hex_tab = Encrypt.hexcase ? \"0123456789ABCDEF\" : \"0123456789abcdef\";\r\n var str = \"\";\r\n for (var i = 0; i < binarray.length * 4; i++) {\r\n str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +\r\n hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);\r\n }\r\n return str;\r\n },\r\n\r\n /*\r\n * Convert an array of little-endian words to a base-64 string\r\n */\r\n binl2b64: function(binarray) {\r\n var tab = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\r\n var str = \"\";\r\n for (var i = 0; i < binarray.length * 4; i += 3) {\r\n var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16) |\r\n (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8) |\r\n ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF);\r\n\r\n for (var j = 0; j < 4; j++) {\r\n if (i * 8 + j * 6 > binarray.length * 32)\r\n str += Encrypt.b64pad;\r\n else\r\n str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);\r\n }\r\n }\r\n return str;\r\n }\r\n};","\r\nLibrarian.Session = new Class({\r\n Binds: [\"onResetComplete\", \"onUpdateComplete\", \"onLogon\", \"onLogoff\", \"onFailure\"],\r\n Implements: [Events, Options],\r\n\r\n options: {\r\n },\r\n\r\n initialize: function(options) {\r\n this.setOptions(options);\r\n },\r\n\r\n logon: function(username, password, params) {\r\n // Get current time zone\r\n var tz = -(new Date()).getTimezoneOffset() / 60;\r\n var url = Librarian.path.getMethodUrl(\"logon\") + \"&out=ujson&utz=\" + tz.toString();\r\n\r\n if (params) {\r\n url += \"&\" + Librarian.Utils.getQueryString(params);\r\n }\r\n\r\n var data = {\r\n username: username,\r\n password: password\r\n };\r\n\r\n if (Librarian.sessionType == Librarian.Session.sessionTypes.onBehalf)\r\n // Pass onBehalfID (stored in userInfo) to stay logged in on behalf\r\n url += \"&obuid=\" + Librarian.userInfo.UserId;\r\n\r\n new Request.JSON({\r\n method: \"post\",\r\n urlEncoded: true,\r\n url: url,\r\n data: data,\r\n noCache: true,\r\n onSuccess: this.onLogon,\r\n onFailure: this.onFailure\r\n }).send();\r\n },\r\n\r\n logoff: function() {\r\n new Request({\r\n method: \"get\",\r\n url: Librarian.path.getMethodUrl(\"logoff\"),\r\n noCache: true,\r\n onSuccess: this.onLogoff,\r\n onFailure: this.onFailure\r\n }).send();\r\n },\r\n\r\n changePassword: function(oldPassword, newPassword, securityQuestion, securityAnswer) {\r\n var url = Librarian.path.getUpdateUrl(\"setup\") + \"&out=cjson\";\r\n\r\n var params = {\r\n uopw: oldPassword,\r\n unpw: newPassword\r\n }\r\n\r\n if (securityQuestion != null) {\r\n params.uq = securityQuestion;\r\n params.ua = securityAnswer;\r\n }\r\n\r\n new Request({\r\n url: url,\r\n method: \"post\",\r\n data: params,\r\n noCache: true\r\n }).addEvent(\"success\", this.onUpdateComplete).addEvent(\"failure\", this.onFailure).send();\r\n },\r\n\r\n sendResetPassword: function(username) {\r\n var url = Librarian.path.getRecoverUrl(\"sendresetpass\") + \"&out=cjson\";\r\n\r\n var params = {\r\n name: username\r\n }\r\n\r\n new Request({\r\n url: url,\r\n method: \"post\",\r\n data: params,\r\n noCache: true\r\n }).addEvent(\"success\", this.onSendResetPassword).send();\r\n },\r\n\r\n onSendResetPassword: function() {\r\n Librarian.Utils.notification(\"Password reset sent\");\r\n },\r\n\r\n onUpdateComplete: function() {\r\n this.fireEvent(\"updatecomplete\", arguments);\r\n },\r\n\r\n onLogon: function() {\r\n this.fireEvent(\"logon\", arguments);\r\n },\r\n\r\n onLogoff: function() {\r\n this.fireEvent(\"logoff\", arguments);\r\n },\r\n\r\n onFailure: function() {\r\n this.fireEvent(\"error\", arguments);\r\n }\r\n});\r\n\r\n/* Static methods and variables */\r\nLibrarian.Session.extend({\r\n sessionTypes: {\r\n undefined: 0,\r\n user: 1,\r\n contactAsGuest: 2,\r\n userAsGuest: 3,\r\n anonymous: 4,\r\n onBehalf: 5,\r\n sso: 6\r\n },\r\n\r\n // Checks if the session is that of a user (type user or sso) or someone on behalf of a user (type onBehalf)\r\n isUser: function(sessionType) {\r\n return (sessionType == Librarian.Session.sessionTypes.user) ||\r\n (sessionType == Librarian.Session.sessionTypes.onBehalf) ||\r\n (sessionType == Librarian.Session.sessionTypes.sso);\r\n },\r\n\r\n isMfaRequired: function(xhr) {\r\n var value = xhr.getResponseHeader(\"X-MFA-Required\");\r\n if (!value)\r\n return false;\r\n\r\n return value.toLowerCase() == \"true\";\r\n }\r\n});\r\n\r\nLibrarian.Session.MFAPanel = new Class({\r\n Implements: [Events, Options],\r\n Binds: [\"onLoadHtml\", \"submit\", \"onSuccess\", \"onFailure\"],\r\n\r\n options: {\r\n container: null,\r\n mfaInfo: null,\r\n credentials: null,\r\n onSuccess: null\r\n },\r\n\r\n containerEl: null,\r\n wrapperEl: null,\r\n\r\n initialize: function(options) {\r\n this.setOptions(options);\r\n\r\n this.containerEl = $(this.options.container);\r\n\r\n this.loadHtml();\r\n },\r\n\r\n loadHtml: function() {\r\n var url = Librarian.path.getLayoutsPath() + \"pages/mfapanel.html\";\r\n\r\n var request = new Request.HTML({\r\n url: url,\r\n method: \"get\",\r\n append: this.containerEl,\r\n onSuccess: this.onLoadHtml\r\n });\r\n\r\n request.send();\r\n },\r\n\r\n onLoadHtml: function() {\r\n var mfaInfo = this.options.mfaInfo;\r\n\r\n this.wrapperEl = this.containerEl.getElement(\".mfa-wrapper\");\r\n\r\n if (mfaInfo.Status == \"MfaSetupRequired\") {\r\n var setupWrapper = this.wrapperEl.getElement(\".mfa-setup-wrapper\");\r\n if (setupWrapper)\r\n setupWrapper.show();\r\n\r\n var setupImg = this.wrapperEl.getElement(\".mfa-setup-image\");\r\n if (setupImg)\r\n setupImg.src = mfaInfo.ImageUrl;\r\n }\r\n\r\n this.codeInput = this.wrapperEl.getElement(\".mfa-code-input\");\r\n this.codeInput.focus();\r\n this.codeInput.addOnKeyPress(\"enter\", this.submit);\r\n\r\n this.submitButton = this.wrapperEl.getElement(\".mfa-code-submit\");\r\n this.submitButton.addOnClick(this.submit);\r\n\r\n this.fireEvent(\"load\");\r\n },\r\n\r\n toggleDisabled: function(disabled) {\r\n this.wrapperEl.toggleClass(\"disabled\", disabled);\r\n this.codeInput.disabled = disabled;\r\n this.submitButton.disabled = disabled;\r\n },\r\n\r\n submit: function() {\r\n if (this.wrapperEl.hasClass(\"disabled\"))\r\n return;\r\n\r\n this.toggleDisabled(true);\r\n\r\n var credentials = this.options.credentials;\r\n\r\n var params = {\r\n mfaSecret: this.options.mfaInfo.Secret,\r\n mfaCode: this.codeInput.value\r\n };\r\n\r\n var session = new Librarian.Session();\r\n session.onLogon = this.onSuccess;\r\n session.onFailure = this.onFailure;\r\n\r\n session.logon(credentials.username, credentials.password, params);\r\n },\r\n\r\n onSuccess: function(sessionInfo) {\r\n if (typeof this.options.onSuccess == \"function\")\r\n this.options.onSuccess(sessionInfo);\r\n },\r\n\r\n onFailure: function(xhr) {\r\n this.toggleDisabled(false);\r\n\r\n var status = null;\r\n\r\n if (Librarian.Session.isMfaRequired(xhr)) {\r\n var errorInfo = JSON.parse(xhr.responseText);\r\n status = errorInfo.Status;\r\n }\r\n\r\n var message = this.getErrorMessage(status);\r\n\r\n Librarian.Utils.error(message);\r\n },\r\n\r\n getErrorMessage: function(status) {\r\n switch(status) {\r\n case \"MfaSetupRequired\":\r\n return \"Authenticator setup is required\";\r\n case \"MfaCodeRequired\":\r\n return \"Verification code is required\";\r\n case \"MfaInvalidCode\":\r\n return \"Verification code is invalid. Please try again.\";\r\n default:\r\n return \"An unexpected error occurred. Please try again.\";\r\n }\r\n }\r\n});\r\n","// Array Remove - By John Resig (MIT Licensed)\r\nif (typeof Array.prototype.remove != \"function\") {\r\n Array.prototype.remove = function(from, to) {\r\n var rest = this.slice((to || from) + 1 || this.length);\r\n this.length = from < 0 ? this.length + from : from;\r\n return this.push.apply(this, rest);\r\n };\r\n}\r\n\r\n// Array Find - From jsPolyfill\r\nif (typeof Array.prototype.find != \"function\") {\r\n Array.prototype.find = function(predicate) {\r\n if (typeof predicate !== 'function') {\r\n throw new TypeError('Predicate is not a function');\r\n }\r\n\r\n var list = Object(this);\r\n // Makes sures is always has an positive integer as length.\r\n var length = list.length >>> 0;\r\n var thisArg = arguments[1];\r\n\r\n for (var i = 0; i < length; i++) {\r\n var element = list[i];\r\n if (predicate.call(thisArg, element, i, list)) {\r\n return element;\r\n }\r\n }\r\n };\r\n}\r\n\r\n// Add the given item to the top of this Array\r\nif (typeof Array.pushTop != \"function\") {\r\n Array.pushTop = function(array, item) {\r\n return Array.from(item).concat(array);\r\n };\r\n}\r\n\r\n/*\r\n * Array intersect by Alexander Herrmann (MIT Licensed)\r\n * From: http://mootools.net/forge/p/array_more\r\n * Creates an intersection of the current array and the given one.\r\n */\r\nArray.implement({\r\n intersect: function(other) {\r\n var copy = this.slice();\r\n this.each(function(el) {\r\n if (other.indexOf(el) < 0) {\r\n copy.splice(copy.indexOf(el), 1);\r\n }\r\n }, this);\r\n return copy;\r\n }\r\n});\r\n\r\nObject.extend({\r\n toArray: function(object, fn) {\r\n var results = [];\r\n\r\n Object.each(object, function(value, key) {\r\n var item = fn(value, key);\r\n results.push(item);\r\n });\r\n\r\n return results;\r\n }\r\n});\r\n\r\n/**\r\n* replaceAll by Fagner Brack (MIT Licensed)\r\n* Replaces all occurrences of a substring in a string\r\n*/\r\nif (typeof String.prototype.replaceAll != \"function\") {\r\n String.prototype.replaceAll = function(token, newToken, ignoreCase) {\r\n var str, i = -1, _token;\r\n if ((str = this.toString()) && typeof token === \"string\") {\r\n _token = ignoreCase === true ? token.toLowerCase() : undefined;\r\n while ((i = (\r\n _token !== undefined ?\r\n str.toLowerCase().indexOf(\r\n _token,\r\n i >= 0 ? i + newToken.length : 0\r\n ) : str.indexOf(\r\n token,\r\n i >= 0 ? i + newToken.length : 0\r\n )\r\n )) !== -1) {\r\n str = str.substring(0, i)\r\n .concat(newToken)\r\n .concat(str.substring(i + token.length));\r\n }\r\n }\r\n return str;\r\n };\r\n}\r\n\r\nif (typeof String.prototype.equalsIgnoreCase != \"function\") {\r\n String.prototype.equalsIgnoreCase = function(str) {\r\n return this.toLowerCase() == str.toLowerCase();\r\n };\r\n}\r\n\r\nif (typeof String.prototype.containsIgnoreCase != \"function\") {\r\n String.prototype.containsIgnoreCase = function(str) {\r\n str = str.toLowerCase();\r\n\r\n return this.toLowerCase().contains(str);\r\n };\r\n}\r\n\r\nif (typeof String.prototype.startsWith != \"function\") {\r\n String.prototype.startsWith = function(str) {\r\n return this.indexOf(str) == 0;\r\n };\r\n}\r\n\r\nif (typeof String.prototype.startsWithIgnoreCase != \"function\") {\r\n String.prototype.startsWithIgnoreCase = function(str) {\r\n str = str.toLowerCase();\r\n\r\n return this.toLowerCase().startsWith(str);\r\n };\r\n}\r\n\r\nif (typeof String.prototype.endsWith != \"function\") {\r\n String.prototype.endsWith = function(str) {\r\n var index = this.lastIndexOf(str);\r\n\r\n return (index >= 0) && (index == (this.length - str.length));\r\n };\r\n}\r\n\r\nif (typeof String.prototype.endsWithIgnoreCase != \"function\") {\r\n String.prototype.endsWithIgnoreCase = function(str) {\r\n str = str.toLowerCase();\r\n\r\n return this.toLowerCase().endsWith(str);\r\n };\r\n}\r\n\r\nif (typeof String.prototype.matches != \"function\") {\r\n String.prototype.matches = function(key, operator) {\r\n if ((typeof operator == \"undefined\") || (operator == null))\r\n operator = \"contains\";\r\n\r\n if ((typeof key != \"undefined\") && (key != null)) {\r\n var self = this.toLowerCase();\r\n key = key.toLowerCase();\r\n operator = operator.toLowerCase();\r\n\r\n return (((operator == \"startswith\") && self.startsWith(key)) ||\r\n ((operator == \"endswith\") && self.endsWith(key)) ||\r\n ((operator == \"equals\") && (self == key)) ||\r\n ((operator == \"contains\") && self.indexOf(key) >= 0));\r\n }\r\n\r\n return false;\r\n };\r\n}\r\n\r\nif (typeof String.prototype.isLowerCase != \"function\") {\r\n String.prototype.isLowerCase = function() {\r\n return this == this.toLowerCase();\r\n };\r\n}\r\n\r\nif (typeof String.prototype.isUpperCase != \"function\") {\r\n String.prototype.isUpperCase = function() {\r\n return this == this.toUpperCase();\r\n };\r\n}\r\n\r\nif (typeof String.isCharLowerCase != \"function\") {\r\n String.isCharLowerCase = function(character) {\r\n return character == character.toLowerCase();\r\n };\r\n}\r\n\r\nif (typeof String.isCharUpperCase != \"function\") {\r\n String.isCharUpperCase = function(character) {\r\n return character == character.toUpperCase();\r\n };\r\n}\r\n\r\nif (typeof String.prototype.isQuoted != \"function\") {\r\n String.prototype.isQuoted = function(quote) {\r\n if ((typeof quote == \"undefined\") || (quote == null))\r\n quote = '\"';\r\n\r\n return this.trim().startsWith(quote) && this.trim().endsWith(quote);\r\n };\r\n}\r\n\r\nif (typeof String.prototype.toCapitalCase != \"function\") {\r\n String.prototype.toCapitalCase = function(lowerRest) {\r\n if ((typeof lowerRest == \"undefined\") || (lowerRest == null))\r\n lowerRest = true;\r\n\r\n var capital = new StringBuffer();\r\n capital.append(this.charAt(0).toUpperCase());\r\n var rest = this.substring(1);\r\n if (lowerRest)\r\n rest = rest.toLowerCase();\r\n capital.append(rest);\r\n return capital.toString();\r\n };\r\n}\r\n\r\nif (typeof String.prototype.toPrettyFormat != \"function\") {\r\n String.prototype.toPrettyFormat = function() {\r\n var words = [],\r\n lastUpper;\r\n\r\n var subWords = this.split(' ');\r\n for (var i = 0; i < subWords.length; i++) {\r\n lastUpper = 0;\r\n for (var j = 1; j < subWords[i].length; j++) {\r\n if (String.isCharUpperCase(subWords[i].charAt(j))) {\r\n words.push(subWords[i].substring(lastUpper, j));\r\n lastUpper = j;\r\n }\r\n }\r\n\r\n if (lastUpper < subWords[i].length)\r\n words.push(subWords[i].substring(lastUpper, subWords[i].length));\r\n }\r\n\r\n for (var i = 0; i < words.length; i++)\r\n words[i] = words[i].toCapitalCase().trim();\r\n\r\n return words.join(' ');\r\n };\r\n}\r\n\r\n/**\r\n* setCharAt by Helder Magalhães\r\n*\r\n* http://www.openjs.com/scripts/strings/setcharat_function.php\r\n*/\r\nif (typeof String.prototype.setCharAt != \"function\") {\r\n String.prototype.setCharAt = function(index, chr) {\r\n if (index > this.length - 1)\r\n return this;\r\n return this.substr(0, index) + chr + this.substr(index + 1);\r\n };\r\n}\r\n\r\n/**\r\n* safeSplit by Michael Lebson\r\n* Safely splits a string by the given token without\r\n* destroying the occurances of the token in the string.\r\n*/\r\nif (typeof String.prototype.safeSplit != \"function\") {\r\n String.prototype.safeSplit = function(token) {\r\n var word = this;\r\n var split = [];\r\n var tokenIndex = -1;\r\n\r\n // Go through each character\r\n for (var i = 0; i < word.length; i++) {\r\n // If this letter is the token\r\n if (word.charAt(i) == token) {\r\n // Save the location, if we don't have one already\r\n if (tokenIndex < 0)\r\n tokenIndex = i;\r\n // Otherwise, do some processing\r\n else {\r\n // If this token isn't at the beginning of the string,\r\n // add the part before it to the list of split values\r\n if (tokenIndex != 0)\r\n split.push(word.substring(0, tokenIndex));\r\n\r\n // Get the value between the first token\r\n // and this one and then save it\r\n split.push(word.substring(tokenIndex, i + 1));\r\n\r\n // Chop off the beginning of this word so we don't process it again\r\n word = word.substring(i + 1, word.length);\r\n // Start back at the beginning of the word\r\n i = 0;\r\n // And reset the token index\r\n tokenIndex = -1;\r\n }\r\n }\r\n }\r\n\r\n // Add the rest of the word to the split list\r\n split.push(word);\r\n\r\n // Return the split list\r\n return split;\r\n };\r\n}\r\n\r\n/**\r\n* Decodes xml-encoded strings\r\n*\r\n* From https://github.com/jnbdz/EncodeAndDecodeXML\r\n*/\r\n\r\nif (typeof String.prototype.decodeXML != \"function\") {\r\n String.prototype.decodeXML = function() {\r\n var escaped_to_xml = {\r\n '&': '&',\r\n '"': '\"',\r\n '<': '<',\r\n '>': '>',\r\n ''': \"'\"\r\n };\r\n\r\n return this.replace(/("|<|>|&|')/g, function (str, item) {\r\n return escaped_to_xml[item];\r\n });\r\n };\r\n}\r\n\r\nif (typeof String.prototype.encodeXML != \"function\") {\r\n String.prototype.encodeXML = function() {\r\n var xml_to_escaped = {\r\n '&': '&',\r\n '\"': '"',\r\n '<': '<',\r\n '>': '>',\r\n \"'\": '''\r\n };\r\n return String(this).replace(/([\\&\"<>'])/g, function(str, item) {\r\n return xml_to_escaped[item];\r\n });\r\n };\r\n}\r\n\r\n/**\r\n* Implements toISOString function for dates in older browsers (e.g. IE 8)\r\n*/\r\nif (typeof Date.prototype.toISOString != \"function\") {\r\n (function() {\r\n function pad(number) {\r\n var r = String(number);\r\n if (r.length === 1)\r\n r = '0' + r;\r\n\r\n return r;\r\n }\r\n\r\n Date.prototype.toISOString = function() {\r\n return this.getUTCFullYear()\r\n + '-' + pad(this.getUTCMonth() + 1)\r\n + '-' + pad(this.getUTCDate())\r\n + 'T' + pad(this.getUTCHours())\r\n + ':' + pad(this.getUTCMinutes())\r\n + ':' + pad(this.getUTCSeconds())\r\n + '.' + String((this.getUTCMilliseconds() / 1000).toFixed(3)).slice(2, 5)\r\n + 'Z';\r\n };\r\n }());\r\n}\r\n\r\n/*\r\n* JavaScript Pretty Date\r\n* Copyright (c) 2011 John Resig (ejohn.org)\r\n* Licensed under the MIT and GPL licenses.\r\n*/\r\nif (typeof Date.prototype.toPrettyFormat != \"function\") {\r\n (function() {\r\n var SECONDS_IN_MINUTE = 60,\r\n MINUTES_IN_HOUR = 60,\r\n HOURS_IN_DAY = 24,\r\n DAYS_IN_WEEK = 7,\r\n SECONDS_IN_HOUR = SECONDS_IN_MINUTE * MINUTES_IN_HOUR,\r\n SECONDS_IN_DAY = SECONDS_IN_HOUR * HOURS_IN_DAY;\r\n\r\n // Takes an ISO time and returns a string showing how long ago the date represents\r\n Date.prototype.toPrettyFormat = function(relativeDate, showAgo, useShortName) {\r\n var now = relativeDate || (new Date()),\r\n secDiff = (now.getTime() - this.getTime()) / 1000,\r\n dayDiff = Math.floor(secDiff / SECONDS_IN_DAY),\r\n translateSuffix = (showAgo !== false ? \"_ago\" : '') + (useShortName !== false ? \"_short\" : '');\r\n\r\n if (isNaN(dayDiff) || (dayDiff < 0))\r\n return Librarian.Lang.getString(\"recently\");\r\n\r\n if (dayDiff == 0) {\r\n if (secDiff < SECONDS_IN_MINUTE)\r\n return Librarian.Lang.getArgString(\"seconds\" + translateSuffix, [Math.ceil(secDiff)]);\r\n if (secDiff < SECONDS_IN_HOUR) {\r\n var minutes = Math.floor(secDiff / SECONDS_IN_MINUTE);\r\n return Librarian.Lang.getPluralArgString(\"minutes\" + translateSuffix, minutes, [minutes]);\r\n }\r\n\r\n var hours = Math.floor(secDiff / SECONDS_IN_HOUR);\r\n return Librarian.Lang.getPluralArgString(\"hours\" + translateSuffix, hours, [hours]);\r\n }\r\n else if (dayDiff == 1)\r\n return Librarian.Lang.getString(\"yesterday\");\r\n else if (dayDiff < DAYS_IN_WEEK)\r\n return Librarian.Lang.getPluralArgString(\"days\" + translateSuffix, dayDiff, [dayDiff]);\r\n\r\n var weeks = Math.floor(dayDiff / DAYS_IN_WEEK);\r\n return Librarian.Lang.getPluralArgString(\"weeks\" + translateSuffix, weeks, [weeks]);\r\n };\r\n }());\r\n}\r\n\r\n/**\r\n* If the browser can't handle ISO strings, add Date.fromISO to parse it\r\n*\r\n* from http://stackoverflow.com/questions/11020658/javascript-json-date-parse-in-ie7-ie8-returns-nan\r\n*/\r\n(function() {\r\n var D = new Date('2011-06-02T09:34:29+02:00');\r\n if (!D || +D !== 1307000069000) {\r\n Date.fromISO = function(s) {\r\n var day, tz,\r\n rx = /^(\\d{4}\\-\\d\\d\\-\\d\\d([tT ][\\d:\\.]*)?)([zZ]|([+\\-])(\\d\\d):(\\d\\d))?$/,\r\n p = rx.exec(s) || [];\r\n if (p[1]) {\r\n day = p[1].split(/\\D/);\r\n for (var i = 0, L = day.length; i < L; i++) {\r\n day[i] = parseInt(day[i], 10) || 0;\r\n };\r\n day[1] -= 1;\r\n day = new Date(Date.UTC.apply(Date, day));\r\n if (!day.getDate()) return NaN;\r\n if (p[5]) {\r\n tz = (parseInt(p[5], 10) * 60);\r\n if (p[6]) tz += parseInt(p[6], 10);\r\n if (p[4] == '+') tz *= -1;\r\n if (tz) day.setUTCMinutes(day.getUTCMinutes() + tz);\r\n }\r\n return day;\r\n }\r\n return new Date(s);\r\n }\r\n }\r\n else {\r\n Date.fromISO = function(s) {\r\n return new Date(s);\r\n }\r\n }\r\n})();\r\n\r\n/**\r\n* Implementation of selectSingleNode for browsers that do not already have it.\r\n*\r\n* Adapted from code from\r\n* http://weblogs.asp.net/ssargent/archive/2007/01/25/selectsinglenode-and-firefox.aspx\r\n*/\r\nif (typeof Element.prototype.selectSingleNode != \"function\") {\r\n Element.implement({\r\n selectSingleNode: function(xPath) {\r\n if (typeof XPathEvaluator == \"undefined\")\r\n return null;\r\n\r\n var pathEvaluator = new XPathEvaluator(),\r\n // FIRST_ORDERED_NODE_TYPE returns the first match to the xpath\r\n result = pathEvaluator.evaluate(xPath, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);\r\n\r\n if (result != null)\r\n return result.singleNodeValue;\r\n else\r\n return null;\r\n }\r\n });\r\n}\r\n\r\nif ((typeof XMLDocument != \"undefined\") && (typeof XMLDocument.prototype.selectSingleNode != \"function\")) {\r\n XMLDocument.prototype.selectSingleNode = function(xPath) {\r\n if (typeof XPathEvaluator == \"undefined\")\r\n return null;\r\n\r\n var pathEvaluator = new XPathEvaluator(),\r\n // FIRST_ORDERED_NODE_TYPE returns the first match to the xpath\r\n result = pathEvaluator.evaluate(xPath, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);\r\n\r\n if (result != null)\r\n return result.singleNodeValue;\r\n else\r\n return null;\r\n };\r\n}\r\n\r\n/**\r\n* Implementation of selectNodes for browsers that do not already have it.\r\n*\r\n* Adapted from code from\r\n* http://www.yesjames.com/index.php/2008/11/firefox-compatible-xpath-functions-in-javascript/\r\n*/\r\nif ((typeof XMLDocument != \"undefined\") && (typeof XMLDocument.prototype.selectNodes != \"function\")) {\r\n XMLDocument.prototype.selectNodes = function(cXPathString, xNode) {\r\n if (!xNode)\r\n xNode = this;\r\n\r\n var oNSResolver = this.createNSResolver(this.documentElement),\r\n aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null),\r\n aResult = [];\r\n for (var i = 0; i < aItems.snapshotLength; i++)\r\n aResult[i] = aItems.snapshotItem(i);\r\n\r\n return aResult;\r\n };\r\n}\r\n\r\nif (typeof Element.prototype.selectNodes != \"function\") {\r\n Element.implement({\r\n selectNodes: function(cXPathString) {\r\n if (this.ownerDocument.selectNodes)\r\n return this.ownerDocument.selectNodes(cXPathString, this);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n* Converts a number into a thousands-separated string using the number of decimals,\r\n* the decimal mark, and the thousands separator provided.\r\n*\r\n* Adapted from code by Patrick Desjardins and Marco Demaio\r\n* http://stackoverflow.com/questions/149055/how-can-i-format-numbers-as-money-in-javascript\r\n*/\r\nif (typeof Number.prototype.toMoney != \"function\") {\r\n Number.prototype.toMoney = function(decimals, symbol, decimalMark, seperator) {\r\n // Default to two decimals if no count or an invalid one are provided\r\n if ((typeof decimals == \"undefined\") || (decimals == null) || isNaN(decimals))\r\n decimals = 2;\r\n else\r\n decimals = Math.abs(decimals);\r\n\r\n if ((typeof symbol == \"undefined\") || (symbol == null))\r\n symbol = '$';\r\n if ((typeof decimalMark == \"undefined\") || (decimalMark == null))\r\n decimalMark = '.';\r\n if ((typeof seperator == \"undefined\") || (seperator == null))\r\n seperator = ',';\r\n\r\n var number = Math.abs(this).toFixed(decimals);\r\n var intPart = parseInt(number).toString();\r\n var seperatorCount = 0;\r\n if (intPart.length > 3)\r\n seperatorCount = intPart.length % 3;\r\n\r\n var value = new StringBuffer();\r\n\r\n if (this < 0)\r\n value.append('-');\r\n\r\n value.append(symbol);\r\n if (seperatorCount > 0) {\r\n value.append(intPart.substr(0, seperatorCount));\r\n value.append(seperator);\r\n }\r\n\r\n value.append(intPart.substr(seperatorCount).replace(/(\\d{3})(?=\\d)/g, \"$1\" + seperator));\r\n if (decimals > 0) {\r\n value.append(decimalMark);\r\n value.append(Math.abs(number - intPart).toFixed(decimals).slice(2));\r\n }\r\n\r\n return value.toString();\r\n };\r\n}\r\n\r\n/**\r\n* Adds the onhashchange event\r\n*\r\n* authors:\r\n* sdf1981cgn\r\n* Greggory Hernandez\r\n*/\r\nElement.Events.hashchange = {\r\n onAdd: function() {\r\n var hash = self.location.hash;\r\n\r\n var hashchange = function() {\r\n if (hash == self.location.hash) return;\r\n else hash = self.location.hash;\r\n\r\n var value = (hash.indexOf('#/') == 0 ? hash.substr(2) : hash.indexOf('#') == 0 ? hash.substr(1) : hash);\r\n window.fireEvent(\"hashchange\", value);\r\n document.fireEvent(\"hashchange\", value);\r\n };\r\n\r\n if (\"onhashchange\" in window)\r\n window.onhashchange = hashchange;\r\n else\r\n hashchange.periodical(50);\r\n }\r\n};\r\n\r\n/**\r\n* Element visibility function by WM\r\n*/\r\nElement.implement({\r\n setVisible: function(visible) {\r\n if (visible === true || visible == \"visible\")\r\n this.setStyle(\"visibility\", \"visible\");\r\n else\r\n this.setStyle(\"visibility\", \"hidden\");\r\n }\r\n});\r\n\r\n/**\r\n* Adds selected class to current element and removes from siblings\r\n* Arguments:\r\n* activeClass (optional): Class to add/remove from elements. Defaults to \"active\"\r\n* siblingSelector (optional): CSS selector to match siblings\r\n*\r\n* Added by WM - 9/24/13\r\n*/\r\nElement.implement({\r\n select: function(activeClass, siblingSelector) {\r\n if (!activeClass)\r\n activeClass = \"active\";\r\n\r\n var siblings = this.getSiblings(siblingSelector);\r\n siblings.forEach(function(sibling) {\r\n sibling.removeClass(activeClass);\r\n });\r\n\r\n this.addClass(activeClass);\r\n }\r\n});\r\n\r\n/**\r\n* Shows this element while hiding siblings\r\n*/\r\nElement.implement({\r\n showOnly: function (siblingSelector) {\r\n var siblings = this.getSiblings(siblingSelector);\r\n siblings.forEach(function (sibling) {\r\n sibling.hide();\r\n });\r\n\r\n this.show();\r\n }\r\n});\r\n\r\n/*\r\n * IE workaround for remove\r\n */\r\nif (typeof Element.prototype.remove != \"function\") {\r\n Element.prototype.remove = function() {\r\n if (typeof this.removeNode == \"function\")\r\n this.removeNode(true);\r\n }\r\n}\r\n\r\n\r\n/**\r\n* String buffer implementation by Jon Brito\r\n*/\r\nfunction StringBuffer() {\r\n this.buffer = [];\r\n}\r\n\r\nStringBuffer.prototype.prepend = function(string) {\r\n var newBuffer = [];\r\n newBuffer.push(string);\r\n this.buffer = newBuffer.append(this.buffer);\r\n\r\n newBuffer = null;\r\n\r\n return this;\r\n};\r\n\r\nStringBuffer.prototype.append = function(string) {\r\n this.buffer.push(string);\r\n return this;\r\n};\r\n\r\nStringBuffer.prototype.toString = function(delimiter) {\r\n return this.buffer.join(delimiter || '');\r\n};\r\n\r\n/**\r\n* Workaround for IE changing the page title when a URL has a hash and a flash object is embedded\r\n*\r\n* http://stackoverflow.com/questions/4562423/ie-title-changes-to-afterhash-if-the-page-has-a-url-with-and-has-flash-s\r\n*/\r\n\r\nvar originalTitle = document.title.split('#')[0];\r\n\r\nfunction onPropertyChanged(evt) {\r\n if ((evt.propertyName === \"title\") && (document.title !== originalTitle)) {\r\n setTimeout(function() {\r\n document.title = originalTitle;\r\n }, 1);\r\n }\r\n}\r\n\r\nfunction changeTitle(newTitle) {\r\n originalTitle = newTitle;\r\n document.title = newTitle;\r\n}\r\n\r\nif (document.attachEvent)\r\n document.attachEvent(\"onpropertychange\", onPropertyChanged);\r\nelse if (document.addEventListener)\r\n document.addEventListener(\"propertychange\", onPropertyChanged, false);\r\n\r\n/**\r\n* Convert all keys in a given object to lower case\r\n*/\r\nif (typeof Object.toLowerKeys != \"function\") {\r\n Object.toLowerKeys = function(object) {\r\n var output = {};\r\n\r\n for (var key in object) {\r\n if (!object.hasOwnProperty(key))\r\n continue;\r\n\r\n var newKey = key.toLowerCase();\r\n\r\n output[newKey] = object[key];\r\n }\r\n\r\n return output;\r\n };\r\n}\r\n\r\nif (typeof Object.toCamelKeys != \"function\") {\r\n Object.toCamelKeys = function(object) {\r\n var output = {};\r\n\r\n for (var key in object) {\r\n if (!object.hasOwnProperty(key))\r\n continue;\r\n\r\n var newKey = key[0].toLowerCase() + key.substring(1);\r\n\r\n output[newKey] = object[key];\r\n }\r\n\r\n return output;\r\n };\r\n}\r\n\r\nClass.refactor(Scroller, {\r\n start: function() {\r\n this.listener.addEvents({\r\n mouseover: this.bound.attach\r\n //mouseleave: this.bound.detach\r\n });\r\n return this;\r\n },\r\n\r\n stop: function() {\r\n this.listener.removeEvents({\r\n mouseover: this.bound.attach\r\n //mouseleave: this.bound.detach\r\n });\r\n this.detach();\r\n this.timer = clearInterval(this.timer);\r\n return this;\r\n }\r\n});\r\n\r\n(function() {\r\n var origRefactor = Class.refactor;\r\n\r\n Class.refactor = function(original, refactors) {\r\n if (!original) {\r\n if (window.console && window.console.debug)\r\n window.console.debug(\"WARN: Attempting to refactor a class that doesn't exist - This is normal on portals\");\r\n return;\r\n }\r\n origRefactor(original, refactors);\r\n }\r\n})();\r\n\r\n// Extend drag events\r\nObject.append(Element.NativeEvents, {\r\n dragenter: 2,\r\n dragleave: 2,\r\n dragover: 2,\r\n drop: 2\r\n});\r\n\r\n// Return \"blob\" in typeOf()\r\nif (typeof Blob != \"undefined\")\r\n Blob.prototype.$family = function() { return \"blob\"; }\r\n\r\n// Dummy console for browsers that don't have it (e.g. IE) to avoid errors.\r\n// This should get replaced when the console is opened.\r\nif (!window.console) {\r\n window.console = {\r\n log: $empty,\r\n error: $empty,\r\n warn: $empty,\r\n debug: $empty,\r\n trace: $empty\r\n };\r\n}","Librarian.Notification = new Class({\r\n Implements: [Options],\r\n Binds: [\"close\"],\r\n\r\n options: {\r\n message: \"\",\r\n type: null,\r\n closeAfter: false // Time in ms or false to leave open\r\n },\r\n\r\n messageEl: null,\r\n\r\n initialize: function(options) {\r\n this.setOptions(options);\r\n\r\n this.render();\r\n },\r\n\r\n render: function() {\r\n var message = this.options.message.replaceAll(\"\\n\", \"
\");\r\n\r\n this.messageEl = new Element(\"div\", {\r\n html: message,\r\n \"class\": \"notification-message\"\r\n }).inject(Librarian.Notification.containerEl);\r\n\r\n if (this.options.type) {\r\n this.messageEl.addClass(\"notification-type-\" + this.options.type);\r\n }\r\n\r\n this.messageEl.addOnClick(this.close);\r\n\r\n if (this.options.closeAfter > 0) {\r\n setTimeout(this.close, this.options.closeAfter);\r\n }\r\n },\r\n\r\n close: function() {\r\n this.messageEl.remove();\r\n }\r\n});\r\n\r\nLibrarian.Notification.extend({\r\n containerEl: null,\r\n\r\n closeAll: function(type) {\r\n if (!this.containerEl)\r\n return;\r\n\r\n var selector = \".notification-message\";\r\n if (type)\r\n selector += \".notification-type-\" + type;\r\n\r\n var messageEls = this.containerEl.getElements(selector);\r\n\r\n messageEls.invoke(\"remove\");\r\n }\r\n});\r\n\r\nwindow.addEvent(\"load\", function() {\r\n Librarian.Notification.containerEl = new Element(\"div\", {\r\n \"class\": \"notification-container\"\r\n }).inject(document.body);\r\n});\r\n","if (!Librarian.Utils) {\r\n Librarian.Utils = {\r\n toBoolean: function (value) {\r\n if (value == null)\r\n return false;\r\n return value.toLowerCase() == \"true\";\r\n },\r\n\r\n getHash: function () {\r\n var hash = window.location.hash;\r\n hash = hash.indexOf(\"#/\") > -1 ? hash.substring(2) : hash.substring(1);\r\n\r\n return hash;\r\n },\r\n\r\n canDownload: function (data) {\r\n if (Librarian.Utils.isSlideShow(data))\r\n return false;\r\n\r\n // Don't let DeepLink users download GFs and VPs\r\n if (Librarian.isGuest && ((data.groupid > 0) || (data.presid > 0) || data.groupinfo))\r\n return false;\r\n\r\n var ext = Librarian.Utils.getExtensionFromData(data);\r\n return !Librarian.download.excludeTypes.contains(ext);\r\n },\r\n canStream: function (data) {\r\n var ext = Librarian.Utils.getExtensionFromData(data, true);\r\n return (Librarian.preview.allowVideoStreaming && Librarian.extensions.isStreamableVideo(ext)) ||\r\n (Librarian.preview.allowAudioStreaming && Librarian.extensions.isStreamableAudio(ext));\r\n },\r\n createLinkFromString: function (string) {\r\n var exp = /\\(?\\b(http|https):\\/\\/[-A-Za-z0-9+&@#\\/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#\\/%=~_()|]/ig;\r\n\r\n // $& uses the whole match from the regular expression. $1 would just return http or https\r\n return string.replace(exp, '$&');\r\n },\r\n getArrayFromCSV: function (text, skip, delim) {\r\n if ((typeof delim == \"undefined\") || (delim == null))\r\n delim = \"\\t\";\r\n\r\n var values = Librarian.Utils.getArrayFromText(text, skip);\r\n\r\n // Split each value by tabs\r\n for (var i = values.length; i--;) {\r\n // Remove empty strings\r\n if (values[i].trim().length == 0) {\r\n values.remove(i);\r\n continue;\r\n }\r\n\r\n values[i] = values[i].split(new RegExp(\"[\" + delim + \"]\", \"g\"));\r\n }\r\n\r\n return values;\r\n },\r\n getArrayFromFile: function (text, skip) {\r\n return Librarian.Utils.getArrayFromText(text, skip);\r\n },\r\n getObjectromFile: function (text) {\r\n var data = [];\r\n\r\n var selection = Librarian.Utils.getArrayFromFile(text, 1);\r\n var headers = (text.match(/[^\\r\\n]+/)[0].split(/[\\t]/g) || []).map(function (datum) {\r\n return datum.trim();\r\n });\r\n\r\n for (var i = 0, len = selection.length; i < len; i++) {\r\n // Remove empty strings\r\n if (selection[i].trim().length == 0) {\r\n selection.remove(i);\r\n continue;\r\n }\r\n\r\n var columns = selection[i].split(/[\\t]/g);\r\n\r\n var info = {};\r\n Array.each(columns, function (col, index) {\r\n var propName = headers[index];\r\n\r\n info[propName] = col.trim();\r\n });\r\n\r\n data.push(info);\r\n }\r\n\r\n return data;\r\n },\r\n getArrayFromText: function (text, skip) {\r\n // Carriage return and line feed\r\n var cr = /\\\\r/g,\r\n lf = /\\\\n/g;\r\n\r\n var lines = (text || '').split(/\\r?\\n/);\r\n\r\n // Removed escaped carriage return and new line\r\n for (var len = lines.length; len--;) {\r\n lines[len] = lines[len].replace(cr, \"\\r\");\r\n lines[len] = lines[len].replace(lf, \"\\n\");\r\n }\r\n\r\n if ((typeof skip == \"number\") && (skip > 0)) {\r\n return lines.slice(skip);\r\n }\r\n\r\n return lines;\r\n },\r\n error: function(message, closeAfter) {\r\n if (closeAfter == null)\r\n closeAfter = 5000;\r\n\r\n return Librarian.Utils.showNotification(message, \"error\", closeAfter);\r\n },\r\n notification: function(message, closeAfter) {\r\n if (closeAfter == null)\r\n closeAfter = 3000;\r\n\r\n return Librarian.Utils.showNotification(message, \"notification\", closeAfter);\r\n },\r\n showNotification: function(message, type, closeAfter) {\r\n var notification = new Librarian.Notification({\r\n message: message,\r\n type: type,\r\n closeAfter: closeAfter\r\n });\r\n\r\n return notification;\r\n },\r\n closeNotifications: function(type) {\r\n Librarian.Notification.closeAll(type);\r\n },\r\n showCartNotification: function (data, type, success) {\r\n if (!(Librarian.features.fastlane.load && Librarian.FastLane.isEnabled)) {\r\n if (Librarian.cart.showDetailedMessages) {\r\n var itemType = Librarian.Utils.getItemTypeString(data);\r\n\r\n if (type == Librarian.cartNotificationTypes.removed) {\r\n if (success) {\r\n Librarian.Utils.notification(Librarian.Lang.getArgString(\"cart_removed_type\", [itemType]), Librarian.cart.notificationTime);\r\n } else {\r\n Librarian.Utils.notification(Librarian.Lang.getArgString(\"cart_remove_failed\", [itemType]), Librarian.cart.notificationTime);\r\n }\r\n } else if (success) {\r\n Librarian.Utils.notification(Librarian.Lang.getArgString(\"cart_added\", [itemType]), Librarian.cart.notificationTime);\r\n }\r\n }\r\n else {\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_updated\"));\r\n }\r\n }\r\n },\r\n openSendWindow: function (data, options) {\r\n if (!Librarian.event.canShare) {\r\n return null;\r\n }\r\n\r\n if (!options)\r\n options = {};\r\n\r\n var win = new Librarian.EventSendWindow(options, data);\r\n win.show();\r\n\r\n return win;\r\n },\r\n openCampaignWindow: function (options) {\r\n if (!options.campaignInfo)\r\n throw \"No campaign info\";\r\n\r\n if (options.campaignInfo.isdraft) {\r\n var confirm = new Librarian.ConfirmWindow({\r\n question: Librarian.Lang.getString(\"eventgroup_send_draft?\")\r\n });\r\n\r\n confirm.onFirstButtonClicked = function () {\r\n new Librarian.CampaignWindow(options);\r\n }.bind(this);\r\n }\r\n else\r\n new Librarian.CampaignWindow(options);\r\n },\r\n openURLFile: function (data) {\r\n Librarian.Utils.getSlideText(data, function (json) {\r\n if (json) {\r\n window.open(json.Text.trim(), \"_blank\" + new Date().getTime());\r\n\r\n var logType = Librarian.activityLogType.preview;\r\n\r\n var fileId = data.fileid,\r\n fileName = encodeURIComponent(data.filename || data.name),\r\n url = Librarian.path.getLogUrl(\"logact\") + \"&cntid=\" + fileId + \"&cnttype=1&name=\" + fileName + \"&logtype=\" + logType;\r\n\r\n new Librarian.Request({\r\n url: url,\r\n async: true\r\n }).send();\r\n }\r\n });\r\n },\r\n openUploader: function (callback) {\r\n function doOpen() {\r\n if (Librarian.features.clouduploader.load) {\r\n var cloudUploadWindow = new Librarian.CloudUploadWindow();\r\n\r\n cloudUploadWindow.show();\r\n }\r\n else if (Librarian.features.html5uploadwindow.load && Librarian.Utils.hasHtml5UploadSupport()) {\r\n var html5UploadWindow = new Librarian.Html5UploadWindow({\r\n complete: function (files) {\r\n if (typeof callback == \"function\")\r\n callback(files);\r\n }\r\n });\r\n\r\n html5UploadWindow.show();\r\n }\r\n }\r\n\r\n if (Librarian.upload.disclaimer != null) {\r\n var confirm = new Librarian.ConfirmWindow({\r\n id: \"UploadAgreeWindow\",\r\n height: Librarian.upload.disclaimerHeight,\r\n width: 500,\r\n title: Librarian.Lang.getString(\"disclaimer\"),\r\n firstButtonText: Librarian.Lang.getString(\"agree\"),\r\n secondButtonText: Librarian.Lang.getString(\"cancel\"),\r\n question: Librarian.upload.disclaimer,\r\n resize: false\r\n });\r\n confirm.onFirstButtonClicked = doOpen;\r\n }\r\n else\r\n doOpen();\r\n },\r\n notifyUploadComplete: function (successCount, failureCount) {\r\n var method = \"notification\";\r\n var message = \"\";\r\n\r\n if (successCount > 0)\r\n message += \"
\" + Librarian.Lang.getPluralArgString(\"upload_success_count\", successCount, [successCount]) + \"
\";\r\n\r\n if (failureCount > 0) {\r\n method = \"error\";\r\n message += \"
\" + Librarian.Lang.getPluralArgString(\"upload_failure_count\", failureCount, [failureCount]) + \"
\";\r\n }\r\n\r\n if (message)\r\n Librarian.Utils[method](message, 5000);\r\n\r\n window.fireEvent(\"uploadFile\");\r\n },\r\n getSlideShowURL: function (data, type) {\r\n var url = Librarian.path.getAppPath(\"slideshow\") + '/' + type + \".htm?libName=\" + Librarian.path.getUrlLibraryName(),\r\n loginKey = window.location.search.substring(1).parseQueryString().lkey,\r\n hashData = this.getHash().parseQueryString(),\r\n frameName = '_' + type;\r\n if (Librarian.sessionName)\r\n url += \"&sname=\" + Librarian.sessionName;\r\n if ((typeof loginKey == \"string\") && (loginKey.length > 0))\r\n url += \"&lkey=\" + loginKey;\r\n\r\n // Include any data we have\r\n if (data) {\r\n if (data.presid > 0) {\r\n url += \"&presId=\" + data.presid;\r\n frameName += data.presid;\r\n }\r\n\r\n if (data.catid > 0)\r\n url += \"&catId=\" + data.catid;\r\n else if ((typeof hashData.catid == \"string\") && (hashData.catid.length > 0))\r\n url += \"&catId=\" + hashData.catid;\r\n }\r\n else if ((typeof hashData.catid == \"string\") && (hashData.catid.length > 0))\r\n url += \"&catId=\" + hashData.catid;\r\n\r\n return { url: url, frameName: frameName };\r\n },\r\n openSlideShow: function (data, type) {\r\n var slideShowURL = Librarian.Utils.getSlideShowURL(data, type),\r\n winSize = window.getSize();\r\n\r\n window.open(slideShowURL.url, slideShowURL.frameName + (new Date()).getTime(), \"directories=no,channelmode=yes,resizable=yes,location=yes,height=\" + winSize.y + \",width=\" + winSize.x);\r\n },\r\n getArticleDesignerURL: function () {\r\n return Librarian.path.getAppPath(\"articles\") + \"/designer.htm?libName=\" + Librarian.path.getUrlLibraryName();\r\n },\r\n openArticleDesigner: function () {\r\n var adURL = Librarian.Utils.getArticleDesignerURL();\r\n window.open(adURL);\r\n },\r\n openWorkflowToDo: function () {\r\n Librarian.todoWindow = new Librarian.WorkflowTodoWindow();\r\n Librarian.todoWindow.onDoubleClick = Library.openWorkflowWizardWindow;\r\n if (typeof Library.workflowInstanceClick == \"function\")\r\n Librarian.todoWindow.onClick = Library.workflowInstanceClick;\r\n Librarian.todoWindow.show();\r\n },\r\n getSlideText: function (data, onSuccess, type, onFailure) {\r\n var slidenum = data.slidenumber || 1;\r\n\r\n // Don't log 404 errors\r\n var params = \"&ignoreerror=true\";\r\n\r\n if (data.slideid > 0)\r\n params += \"&sid=\" + data.slideid;\r\n else if (data.fileid > 0)\r\n params += \"&fid=\" + data.fileid + \"&snum=\" + slidenum;\r\n else if (data.presid > 0)\r\n params += \"&pid=\" + data.presid + \"&snum=\" + (data.itemnumber || slidenum);\r\n else if (data.groupid > 0)\r\n params += \"&gid=\" + data.groupid + \"&snum=\" + slidenum;\r\n else if (data.filename && data.filename.length > 0)\r\n params += \"&fname=\" + encodeURIComponent(data.filename) + \"&snum=\" + slidenum;\r\n else\r\n return;\r\n\r\n if ((typeof type != \"undefined\") && (type != null))\r\n params += \"&subtype=\" + type;\r\n\r\n if (Librarian.catType.isUserCategory(data.cattype))\r\n params += \"&useweb=false\";\r\n\r\n new Librarian.Request.JSON({\r\n url: Librarian.path.getMethodUrl(\"getslidetext\") + params + \"&out=ujson\",\r\n onSuccess: onSuccess || $empty,\r\n onFailure: onFailure || $empty\r\n }).send();\r\n },\r\n getSlideTextArray: function (data, onSuccess, type, onFailure) {\r\n Librarian.Utils.getSlideText(data, function (result) {\r\n if (!result || !result.Text) {\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n return;\r\n }\r\n\r\n var array = Librarian.Utils.getArrayFromFile(result.Text);\r\n\r\n if (typeof onSuccess == \"function\")\r\n onSuccess(array);\r\n }, type, onFailure);\r\n },\r\n getFileID: function (fileName, onSuccess, onFailure, ignoreExtension) {\r\n var url = Librarian.path.getMethodUrl(\"getfid\") + \"&out=ljson&fname=\" + encodeURIComponent(fileName);\r\n if (ignoreExtension === true) {\r\n url += \"&ignoreextension=\" + ignoreExtension + \"&cattype=2\";\r\n }\r\n\r\n new Librarian.Request.JSON({\r\n url: url,\r\n onSuccess: onSuccess,\r\n onFailure: function(error) {\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n }\r\n }).send();\r\n },\r\n getFileInfo: function(fileId, onSuccess, onFailure) {\r\n var url = Librarian.path.getMethodUrl(\"getfi\") + \"&out=ljson&fid=\" + encodeURIComponent(fileId);\r\n\r\n new Librarian.Request.JSON({\r\n url: url,\r\n onSuccess: onSuccess,\r\n onFailure: function(error) {\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n }\r\n }).send();\r\n },\r\n deleteUserFile: function(fileId, onSuccess, onFailure) {\r\n var url = Librarian.path.getUpdateUrl(\"deleteuserfile\") + \"&out=ljson&fid=\" + encodeURIComponent(fileId);\r\n\r\n new Librarian.Request.JSON({\r\n url: url,\r\n onSuccess: onSuccess,\r\n onFailure: function(error) {\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n }\r\n }).send();\r\n },\r\n\r\n getFileHash: function (fileid, name, onSuccess, onFailure) {\r\n if (typeof onSuccess != \"function\")\r\n return null;\r\n\r\n var params;\r\n if (fileid > 0)\r\n params = \"&fid=\" + fileid;\r\n else\r\n params = \"&fname=\" + encodeURIComponent(name);\r\n\r\n return new Librarian.Request({\r\n url: Librarian.path.getMethodUrl(\"getfh\") + \"&out=text\" + params,\r\n onSuccess: onSuccess,\r\n async: false,\r\n onFailure: function(error) {\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n }\r\n }).send();\r\n },\r\n getAttributeFromArray: function (attribList, attribName) {\r\n if (!attribList || !attribName)\r\n return null;\r\n\r\n for (var i = 0; i < attribList.length; i++) {\r\n var attrib = attribList[i];\r\n\r\n if ((attrib.name == attribName) || (attrib.Name == attribName))\r\n return attrib.value || attrib.Value;\r\n }\r\n\r\n return null;\r\n },\r\n getAttributesFromArray: function (attribList) {\r\n var attributes = {};\r\n if (attribList) {\r\n for (var i = 0; i < attribList.length; i++) {\r\n var attrib = attribList[i];\r\n\r\n var name = attrib.name || attrib.Name;\r\n var value = attrib.value || attrib.Value;\r\n\r\n attributes[name] = value;\r\n }\r\n }\r\n\r\n return attributes;\r\n },\r\n getAttributeDropdownValues: function (attribId, attribName, onSuccess, onFailure, includeInfo) {\r\n if ((!attribId || (attribId < 0)) && (!attribName || (attribName.length == 0)))\r\n return null;\r\n\r\n var params;\r\n if (attribId && (attribId >= 0))\r\n params = \"&atid=\" + attribId;\r\n else\r\n params = \"&atname=\" + encodeURIComponent(attribName);\r\n\r\n var request = new Librarian.Request.JSON({\r\n url: Librarian.path.getMethodUrl(\"getadv\") + params + \"&out=ujson\",\r\n onFailure: function(error) {\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n },\r\n onSuccess: function (json) {\r\n if (!json)\r\n return;\r\n\r\n if (includeInfo === true) {\r\n onSuccess(json, attribName);\r\n return;\r\n }\r\n\r\n var values = json.map(function (item) {\r\n return item.Value;\r\n });\r\n onSuccess(values, attribName, json);\r\n }\r\n });\r\n request.send();\r\n return request;\r\n },\r\n getFileTypes: function (onSuccess, onFailure) {\r\n var request = new Librarian.Request.JSON({\r\n url: Librarian.path.getMethodUrl(\"getftypes\") + \"&out=ujson\",\r\n onFailure: function(error) {\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n },\r\n onSuccess: onSuccess\r\n });\r\n request.send();\r\n },\r\n getThumbnailUrl: function (size, data, track, expand, parentData) {\r\n var slideNum, itemNum, noSource = false;\r\n if (data) {\r\n // Get the source file's extension (if there is one)\r\n var sourceext = Librarian.Utils.getExtensionFromData(data, true),\r\n // Whether or not this is a file pretending to be a slide\r\n fileAsSlide = Librarian.extensions.hasFakeSlides(sourceext);\r\n\r\n slideNum = data.slidenumber;\r\n\r\n // If there is no slide number, there is an invalid slide number,\r\n // or this is a file pretending to be a slide, use the first \"slide\" in the file\r\n if (!slideNum || (slideNum < 0) || fileAsSlide)\r\n slideNum = 1;\r\n\r\n itemNum = (data.itemnumber || slideNum);\r\n\r\n // If this is a presentation with a -1 slide id and an invalid file type,\r\n // the source isn't available and we should show the \"No Image Available\" image\r\n if (Librarian.Utils.isSourceNotAvailable(data))\r\n noSource = true;\r\n }\r\n else\r\n noSource = true;\r\n\r\n var url = Librarian.path.getThumbnailUrl() + \"&tname=\" + size;\r\n\r\n if (!noSource) {\r\n if (data.editFileName)\r\n url = Librarian.path.getDownloadUrl(\"spv\") + \"&tname=\" + size + \"&fname=\" + encodeURIComponent(data.editFileName);\r\n else if (data.thumbnailid)\r\n url += \"&tnid=\" + data.thumbnailid;\r\n else if (data.presid)\r\n url += \"&pid=\" + data.presid + \"&comp=1&snum=\" + itemNum + \"&expand=\" + ((Librarian.tileList.expandGroupItemsToSlides || (expand === true)) ? '1' : '0');\r\n else if (data.slideid > 0)\r\n url += \"&sid=\" + data.slideid;\r\n else if (data.groupid) {\r\n // If this has an event count, its an event group not a Global Favorite\r\n if (typeof data.eventcount == \"number\")\r\n url += \"&egid=\" + data.groupid + \"&snum=\" + itemNum;\r\n else\r\n url += \"&gid=\" + data.groupid + \"&snum=\" + itemNum + \"&expand=\" + ((expand === true) ? '1' : '0');\r\n }\r\n else if (data.fileid)\r\n url += \"&fid=\" + data.fileid + \"&snum=\" + slideNum;\r\n else if (data.eventid)\r\n url += \"&eid=\" + data.eventid;\r\n else if (data.catid) {\r\n url = Librarian.path.getLibraryPath() + \"img/folder.jpg\";\r\n track = false;\r\n }\r\n else if (data.contentid && data.contenttype)\r\n url += \"&cntid=\" + data.contentid + \"&cnttype=\" + data.contenttype + \"&snum=\" + itemNum;\r\n else if (data.supportfileid)\r\n url += \"&cntid=\" + data.supportfileid + \"&cnttype=\" + Librarian.contentType.supportFile + \"&snum=\" + itemNum;\r\n else {\r\n url = null;\r\n track = false;\r\n }\r\n }\r\n else {\r\n url = null;\r\n track = false;\r\n }\r\n\r\n if (url) {\r\n if (track === true)\r\n url += \"&track=1&\" + String.uniqueID();\r\n else if (data && !data.thumbnailid)\r\n url += \"&cacheid=\" + Librarian.cacheId;\r\n\r\n if (data.instanceid > 0 || (parentData && parentData.instanceid > 0))\r\n url += \"&useweb=false\";\r\n\r\n // Pass the icon path as an alternative\r\n var ext = Librarian.Utils.getExtensionFromData(data);\r\n var altUrl = Librarian.Utils.getFileTypeIcon(ext, 32);\r\n\r\n url += \"&alt=\" + encodeURIComponent(altUrl);\r\n }\r\n else {\r\n url = Librarian.path.getFullPath(Librarian.path.root + \"/img/NotAvailable.jpg\");\r\n }\r\n\r\n return url;\r\n },\r\n\r\n getFileTypeIcon: function (ext, size, category) {\r\n ext = (ext || '').trim().toLowerCase();\r\n category = !!category;\r\n size = size || '';\r\n\r\n var version = Librarian.extensions.fileTypeIconsVersion;\r\n\r\n switch (version) {\r\n case 1:\r\n return this.getFileTypeIcon_v1(ext, size, category);\r\n case 2:\r\n return this.getFileTypeIcon_v2(ext, size, category);\r\n case 3:\r\n return this.getFileTypeIcon_v3(ext, size, category);\r\n default:\r\n return \"\";\r\n }\r\n },\r\n\r\n getFileTypeIcon_v1: function(ext, size, category) {\r\n var fileName;\r\n\r\n if (category) {\r\n fileName = 'CategoryFolder';\r\n if (ext === \"favorite\") {\r\n fileName = \"FavoritesFolder\";\r\n }\r\n\r\n if (size && (typeof size == \"number\")) {\r\n fileName += '_' + size;\r\n }\r\n }\r\n else {\r\n fileName = ext;\r\n\r\n if (size && (typeof size == \"number\")) {\r\n fileName = size + '_' + fileName;\r\n }\r\n }\r\n\r\n fileName += \".gif\";\r\n\r\n return Librarian.path.getFileTypeIconsPath(\"v1\") + fileName;\r\n },\r\n\r\n getFileTypeIcon_v2: function(ext, size, category) {\r\n var fileName;\r\n\r\n if (category) {\r\n if (ext === \"favorite\") {\r\n fileName = \"FAV_Folder\";\r\n }\r\n else {\r\n fileName = \"YEL_Folder\";\r\n }\r\n }\r\n else {\r\n fileName = Librarian.Utils.getFileTypeIconName(ext);\r\n }\r\n\r\n if (typeof size != \"number\")\r\n size = 16;\r\n\r\n fileName += \"_Icon_\" + size + \".png\";\r\n\r\n return Librarian.path.getFileTypeIconsPath(\"v2\") + fileName;\r\n },\r\n\r\n getFileTypeIcon_v3: function(ext, size, category) {\r\n // Use v2 category icons\r\n if (category)\r\n return Librarian.Utils.getFileTypeIcon_v2(ext, size, category);\r\n\r\n var fileName = Librarian.Utils.getFileTypeIconName(ext);\r\n\r\n // Use 2x icons\r\n if (size == 32)\r\n fileName += \"_64\";\r\n else\r\n fileName += \"_32\";\r\n\r\n fileName += \".png\";\r\n\r\n return Librarian.path.getFileTypeIconsPath(\"v3\") + fileName;\r\n },\r\n\r\n getFileTypeIconName: function(ext) {\r\n var type = Librarian.extensions.getFileType(ext);\r\n\r\n var icons = {\r\n powerpoint: \"PowerPoint\",\r\n pdf: \"PDF\",\r\n text: \"Text\",\r\n word: \"Word\",\r\n excel: \"Excel\",\r\n vector: \"Vector\",\r\n image: \"Image\",\r\n video: \"Video\",\r\n audio: \"Audio\",\r\n archive: \"Archive\",\r\n favorite: \"Favorite\",\r\n link: \"Link\",\r\n wizard: \"Wizard\",\r\n campaign: \"Campaign\",\r\n page: \"Page\"\r\n };\r\n\r\n return icons[type] || \"Default\";\r\n },\r\n\r\n getNaturalImageSize: function (imageEl) {\r\n if (!imageEl)\r\n return null;\r\n\r\n var width = imageEl.naturalWidth,\r\n height = imageEl.naturalHeight;\r\n\r\n // If we can't use natural width or height, make a fake image that isn't hidden and pull the size from that\r\n if ((typeof width != \"number\") || isNaN(width) || (typeof height != \"number\") || isNaN(height)) {\r\n var tempImageEl = new Image();\r\n tempImageEl.src = imageEl.src;\r\n\r\n width = tempImageEl.width;\r\n height = tempImageEl.height;\r\n }\r\n\r\n return { x: width, y: height };\r\n },\r\n getFileDownloadUrl: function (data, mode, newName, extension) {\r\n if ((typeof mode == \"undefined\") || (mode == null))\r\n mode = \"dnld\";\r\n var fileid = data.fileid || data,\r\n url = '';\r\n\r\n if (fileid) {\r\n url = Librarian.path.getDownloadUrl() + \"mode=\" + mode + \"&fid=\" + fileid;\r\n\r\n if (newName)\r\n url += \"&name=\" + encodeURIComponent(newName);\r\n if (extension)\r\n url += \"&ext=\" + encodeURIComponent(extension);\r\n }\r\n\r\n if (data.requestid)\r\n url += \"&rid=\" + data.requestid;\r\n\r\n return url;\r\n },\r\n download: function(url, filename) {\r\n if (typeof filename != \"string\")\r\n filename = \"\";\r\n\r\n var link = new Element(\"a\", {\r\n href: url,\r\n download: filename\r\n });\r\n\r\n link.click();\r\n }, \r\n getPath: function (data, onComplete, name) {\r\n if (!data)\r\n return;\r\n if (typeof onComplete != \"function\")\r\n return;\r\n if ((typeof name == \"undefined\") || (name == null))\r\n name = false;\r\n\r\n var method = \"getcpath\",\r\n id = \"&cid=\" + data.catid,\r\n catType = Librarian.catType.file;\r\n\r\n if (data.type != null)\r\n catType = data.type;\r\n else if (data.cattype != null)\r\n catType = data.cattype;\r\n\r\n if (data.groupid > 0) {\r\n method = \"getpath\";\r\n var shortName = \"gid\";\r\n if (data.type == Librarian.catType.event || data.cattype == Librarian.catType.event)\r\n shortName = \"egid\";\r\n\r\n id += '&' + shortName + '=' + data.groupid;\r\n }\r\n else if (data.eventid > 0 && data.parentid) {\r\n method = \"getpath\";\r\n var shortName = \"egid\";\r\n\r\n id += '&' + shortName + '=' + data.parentid;\r\n }\r\n else if (data.presid > 0) {\r\n method = \"getpath\";\r\n id += \"&pid=\" + data.presid;\r\n }\r\n else if (data.fileid > 0) {\r\n method = \"getpath\";\r\n id += \"&fid=\" + data.fileid;\r\n }\r\n else if (typeof data.path == \"string\")\r\n id += \"&cname=\" + encodeURIComponent(data.path);\r\n\r\n var url = Librarian.path.getMethodUrl(method) + \"&catType=\" + catType + id + \"&out=text\";\r\n if (name)\r\n url += \"&name=true\";\r\n\r\n var request = new Librarian.Request({\r\n url: url,\r\n onSuccess: onComplete,\r\n onFailure: function () {\r\n onComplete(null);\r\n }\r\n });\r\n request.send();\r\n },\r\n getCatFromPath: function (path, onComplete, onFailure) {\r\n if (!path)\r\n return;\r\n if (typeof onComplete != \"function\")\r\n return;\r\n\r\n var url = Librarian.path.getMethodUrl(\"getcatfp\") + \"&cpath=\" + path + \"&out=cjson\",\r\n request = new Request.JSON({\r\n url: url,\r\n onSuccess: onComplete,\r\n onFailure: function(error) {\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n }\r\n });\r\n request.send();\r\n },\r\n getSearchContext: function (term, sid, onComplete) {\r\n var request = new Librarian.Request({\r\n url: Librarian.path.getMethodUrl(\"getslidetext\") + \"&out=stext&sid=\" + sid +\r\n \"&sterms=\" + encodeURIComponent(term) +\r\n \"&max=512&mclass=searchContext&mtag=span\",\r\n onSuccess: onComplete\r\n });\r\n request.send();\r\n },\r\n getItemType: function (data) {\r\n if (data) {\r\n var ext = Librarian.Utils.getExtensionFromData(data, true);\r\n if ((data.slideid > 0) || (data.contenttype == Librarian.contentType.slide)) {\r\n if (ext.startsWith(\"ppt\") || ext.startsWith(\"pps\") || ext.startsWith(\"pot\"))\r\n return \"slide\";\r\n else\r\n return \"page\";\r\n }\r\n else if (data.eventid > 0)\r\n return \"event\";\r\n else if (typeof data.eventcount == \"number\")\r\n return \"eventgroup\";\r\n else if ((data.groupid > 0) || (data.presid > 0))\r\n return \"group\";\r\n }\r\n\r\n return \"item\";\r\n },\r\n getItemTypeString: function (data) {\r\n var type = Librarian.Utils.getItemType(data);\r\n\r\n return Librarian.Lang.getString(type);\r\n },\r\n isSourceNotAvailable: function (data) {\r\n return data && (data.presid > 0) && (data.slideid > 0) && (data.slidenumber <= 0);\r\n },\r\n getNameWithoutExtension: function (filename) {\r\n if (!filename)\r\n return '';\r\n\r\n var extIndex = filename.lastIndexOf('.');\r\n if (extIndex < 0)\r\n return filename;\r\n\r\n return filename.substring(0, extIndex);\r\n },\r\n getExtension: function (filename) {\r\n if (!filename)\r\n return '';\r\n\r\n filename = Librarian.Utils.undecorateFileName(filename);\r\n // Get the index of the last . so we can get the extension\r\n var extIndex = filename.lastIndexOf('.');\r\n if (extIndex < 0)\r\n return '';\r\n\r\n return filename.substring(extIndex + 1).toLowerCase();;\r\n },\r\n getExtensionFromData: function (data, includeSource) {\r\n if (!data)\r\n return '';\r\n\r\n data = Object.toLowerKeys(data);\r\n\r\n if ((typeof includeSource == \"undefined\") || (includeSource == null))\r\n includeSource = false;\r\n\r\n var fileData = (data.fileinfo || data.groupinfo || data),\r\n ext = null;\r\n // If we're supposed to include the source, get that first\r\n // The source should only ever be a valid file type, so ignore it if it's \"vpres\" for some reason\r\n if (includeSource && (fileData.sourceext != \"vpres\"))\r\n ext = fileData.sourceext;\r\n\r\n // Get the extension from all the possibilities\r\n ext = ext || fileData.filetypeextension || fileData.ext || '';\r\n // If the extension starts with a ., drop it\r\n if (ext.startsWith('.'))\r\n ext = ext.substring(1);\r\n\r\n // Trim off any whitespace\r\n ext = ext.trim();\r\n\r\n // If we don't have an extension, try to get it from the file name\r\n if (ext.length == 0)\r\n ext = (Librarian.Utils.getExtension(fileData.filename || fileData.contentname || fileData.name) || '').trim();\r\n // If we still don't have an extension, check for special ones\r\n if (ext.length == 0) {\r\n if (fileData.groupid > 0) {\r\n ext = \"favg\";\r\n\r\n // If this has an event count, its an event group not a Global Favorite\r\n if (fileData.eventcount > 0)\r\n ext = \"evtg\";\r\n }\r\n else if (fileData.presid > 0)\r\n ext = \"vpres\";\r\n }\r\n\r\n // Trim whitespace again and return the lowercase\r\n return ext.trim().toLowerCase();\r\n },\r\n getFileNameFromPath: function (fullPath) {\r\n var fileName = '';\r\n if (fullPath)\r\n fileName = fullPath.replace(/^.*[\\\\\\/]/, '');\r\n\r\n return fileName;\r\n },\r\n getRequestInfo: function (requestId, onSuccess, onFailure) {\r\n var request = new Librarian.Request.JSON({\r\n url: Librarian.path.getMethodUrl(\"getr\") + \"&rid=\" + requestId + \"&out=ujson\",\r\n onSuccess: onSuccess,\r\n onFailure: function(error) {\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n }\r\n });\r\n request.send();\r\n },\r\n getLink: function (data, isDownload) {\r\n if (!data)\r\n return null;\r\n\r\n if (Librarian.linkWindow != null) {\r\n Librarian.linkWindow.close();\r\n Librarian.linkWindow = null;\r\n }\r\n\r\n // Make sure we don't have some inner object\r\n data = data.fileinfo || data.groupinfo || data;\r\n\r\n var url = null;\r\n // If this is absolutely a file and we're told to use the download link\r\n if (isDownload &&\r\n (typeof data.fileid == \"number\") && (data.fileid > 0) &&\r\n ((typeof data.groupid != \"number\") || (data.groupid <= 0)) &&\r\n ((typeof data.presid != \"number\") || (data.presid <= 0)) &&\r\n ((typeof data.slideid != \"number\") || (data.slideid <= 0)) &&\r\n ((typeof data.slidenumber != \"number\") || (data.slidenumber <= 0))) {\r\n Librarian.Utils.getFileHash(data.fileid, null, function (hash) {\r\n url = Librarian.path.getRootURL();\r\n // If we have a root, build the whole rest of the URL before the library\r\n if (Librarian.path.root.length > 0)\r\n url += Librarian.path.root + '/' + Librarian.path.libraries;\r\n url += '/' + Librarian.path.getUrlLibraryName() + '/' + Librarian.path.getDownloadUrl(Librarian.pageHeaders.downloadLinkMode) + \"&fh=\" + hash;\r\n });\r\n }\r\n else {\r\n url = window.location.origin + window.location.pathname;\r\n\r\n if (data.fileid) {\r\n url += \"#fileid=\" + data.fileid;\r\n }\r\n else if (data.groupid && data.contenttype == Librarian.contentType.eventGroup) {\r\n url += \"#groupid=\" + data.groupid + \"&type=5\";\r\n if (data.catid) {\r\n url += \"&catid=\" + data.catid;\r\n }\r\n }\r\n else if (data.groupid) {\r\n url += \"#groupid=\" + data.groupid + \"&type=1\";\r\n }\r\n else {\r\n url += window.location.hash;\r\n };\r\n\r\n if (!url.includes(\"catid\") && data.catid && data.contenttype == Librarian.contentType.category) {\r\n url += \"#catid=\" + data.catid + \"&type=\" + data.type;\r\n }\r\n\r\n if (Librarian.pageHeaders.libraryLinkPreview && data.contenttype !== Librarian.contentType.category) {\r\n url += \"&preview=true\";\r\n };\r\n }\r\n\r\n Librarian.linkWindow = new Librarian.InfoWindow({\r\n title: Librarian.Lang.getArgString(\"info_title\", [data.groupname || data.name || data.filename]),\r\n content: url\r\n });\r\n\r\n Librarian.linkWindow.show();\r\n },\r\n getTopRated: function (count, catType, onSuccess, onFailure, outputType, useGetSendData, customSendData) {\r\n var searchType = Librarian.Search.outputTypes.FILES;\r\n if (catType == Librarian.catType.globalFavorite)\r\n searchType = Librarian.Search.outputTypes.GROUPS;\r\n return Librarian.Utils.getFilesByMethod(count, onSuccess, onFailure, \"gettoprated\", searchType, outputType, { type: catType }, useGetSendData, customSendData);\r\n },\r\n getPopular: function (count, contentType, onSuccess, onFailure, outputType, useGetSendData, customSendData) {\r\n var searchType = Librarian.Search.outputTypes.FILES;\r\n if (contentType == Librarian.contentType.globalFavorite)\r\n searchType = Librarian.Search.outputTypes.GROUPS;\r\n else if (contentType == Librarian.contentType.slide)\r\n searchType = Librarian.Search.outputTypes.SLIDES;\r\n return Librarian.Utils.getFilesByMethod(count, onSuccess, onFailure, \"getpopc\", searchType, outputType, { type: contentType }, useGetSendData, customSendData);\r\n },\r\n getNewestFiles: function (count, onSuccess, onFailure, outputType, excludeExtensions, useGetSendData, customSendData) {\r\n return Librarian.Utils.getFilesByMethod(count, onSuccess, onFailure, \"getnewf\", Librarian.Search.outputTypes.FILES, outputType, excludeExtensions ? { exclude: excludeExtensions.join(',') } : null, useGetSendData, customSendData);\r\n },\r\n getNewestGroups: function (count, onSuccess, onFailure, outputType, notUsed, useGetSendData, customSendData) {\r\n return Librarian.Utils.getFilesByMethod(count, onSuccess, onFailure, \"getnewcg\", Librarian.Search.outputTypes.GROUPS, outputType, null, useGetSendData, customSendData);\r\n },\r\n getNewestEventGroups: function (data, extraInfo, onSuccess, onFailure, outputType) {\r\n return Librarian.Utils.getEventGroupsByMethod(onSuccess, onFailure, \"getrecgs\", outputType, data, extraInfo);\r\n },\r\n getPopularEventGroups: function (data, extraInfo, onSuccess, onFailure, outputType) {\r\n return Librarian.Utils.getEventGroupsByMethod(onSuccess, onFailure, \"getpopgs\", outputType, data, extraInfo);\r\n },\r\n getEventGroupsByMethod: function (onSuccess, onFailure, method, outputType, data, extraInfo) {\r\n if (typeof onSuccess != \"function\")\r\n return null;\r\n if ((typeof outputType == \"undefined\") || (outputType == null))\r\n outputType = \"dgrid\";\r\n\r\n var url = Librarian.path.getEventUrl(method) + \"&out=\" + outputType;\r\n\r\n if (extraInfo != null) {\r\n url += \"&exi=\" + extraInfo;\r\n }\r\n\r\n var options = {\r\n url: url,\r\n onSuccess: onSuccess,\r\n onFailure: function(error) {\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n }\r\n };\r\n\r\n if (data) {\r\n // If the given data is an object, stringify it\r\n if (typeof data == \"object\")\r\n data = JSON.stringify(data);\r\n // Convert the data to Base64\r\n if (typeof Base64 != \"undefined\")\r\n data = Base64.encode(data);\r\n\r\n // And save it\r\n options.data = data;\r\n options.method = \"post\";\r\n options.url += \"&in=cjson\";\r\n }\r\n\r\n var request = new Librarian.Request.JSON(options);\r\n request.send();\r\n\r\n return request;\r\n },\r\n getFilesByMethod: function (count, onSuccess, onFailure, method, type, outputType, parameters, useGetSendData, customSendData) {\r\n if (count <= 0)\r\n return null;\r\n if (typeof onSuccess != \"function\")\r\n return null;\r\n if ((typeof outputType == \"undefined\") || (outputType == null))\r\n outputType = \"dgrid\";\r\n if (typeof useGetSendData != \"boolean\")\r\n useGetSendData = true;\r\n\r\n var url = Librarian.path.getMethodUrl(method) + \"&max=\" + count + \"&out=\" + outputType + \"&in=ujson\";\r\n\r\n // If we were given parameters\r\n if ((typeof parameters == \"object\") && (parameters != null)) {\r\n // Add each one\r\n for (var key in parameters) {\r\n if (!parameters.hasOwnProperty(key))\r\n continue;\r\n\r\n url += '&' + key + '=' + encodeURIComponent(parameters[key]);\r\n }\r\n }\r\n\r\n var view = '';\r\n if (Librarian.search.viewNameByType && Librarian.search.viewNameByType[type])\r\n view = \"&vname=\" + Librarian.search.viewNameByType[type];\r\n\r\n if (Librarian.elasticSearch.enableContent) {\r\n url += \"&usees=1\";\r\n\r\n if (Librarian.elasticSearch.includeView)\r\n url += view;\r\n }\r\n else\r\n url += view;\r\n\r\n var options = {\r\n url: url,\r\n onSuccess: onSuccess,\r\n onFailure: function(error) {\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n }\r\n };\r\n\r\n // If we have a custom data function\r\n if (useGetSendData && (typeof Library != \"undefined\") && ((typeof Library.getSendData == \"function\") || (typeof customSendData == \"function\"))) {\r\n var data = {};\r\n if (type == Librarian.Search.outputTypes.FILES)\r\n data.cattype = Librarian.catType.file;\r\n else if (type == Librarian.Search.outputTypes.GROUPS)\r\n data.cattype = Librarian.catType.globalFavorite;\r\n\r\n // Get the data to send and check that it is valid\r\n if ((typeof customSendData == \"function\")) {\r\n data = customSendData(data, options.url);\r\n } else {\r\n data = Library.getSendData(data, options.url);\r\n }\r\n\r\n if (data) {\r\n // If the given data is an object, stringify it\r\n if (typeof data.data == \"object\")\r\n data.data = JSON.stringify(data.data);\r\n // Convert the data to Base64\r\n if (typeof Base64 != \"undefined\")\r\n data.data = Base64.encode(data.data);\r\n\r\n // And save it\r\n options.data = data.data;\r\n options.method = \"post\";\r\n if (data.url)\r\n options.url = data.url;\r\n }\r\n }\r\n\r\n var request = new Librarian.Request.JSON(options);\r\n request.send();\r\n\r\n return request;\r\n },\r\n getNthBusinessDay: function (n, startDate) {\r\n if ((typeof n != \"number\") || (n <= 0))\r\n return null;\r\n\r\n if (!startDate)\r\n startDate = new Date();\r\n\r\n var targetDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());\r\n\r\n while (n > 0) {\r\n targetDate.setDate(targetDate.getDate() + 1);\r\n\r\n // Skip Sunday(0) and Saturday(6)\r\n var dayOfWeek = targetDate.getDay();\r\n if (dayOfWeek == 0 || dayOfWeek == 6)\r\n continue;\r\n\r\n // Skip holidays\r\n if (Librarian.Utils.isHoliday(targetDate))\r\n continue;\r\n\r\n // Otherwise, count this as a business day\r\n n--;\r\n }\r\n\r\n return targetDate;\r\n },\r\n getTopics: function(count, onSuccess, onFailure) {\r\n var url = Librarian.path.getCollaborationUrl(\"gettopics\") + \"&max=\" + count + \"&out=cjson\" + \"&in=cjson\",\r\n options = {\r\n url: url,\r\n onSuccess: onSuccess,\r\n onFailure: function(error) {\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n }\r\n };\r\n\r\n var request = new Librarian.Request.JSON(options);\r\n request.send();\r\n },\r\n isHoliday: function (date) {\r\n var holidays = Librarian.calendar.holidays;\r\n if (!holidays)\r\n return false;\r\n\r\n for (var i = 0; i < holidays.length; i++) {\r\n var holiday = new Date(holidays[i]);\r\n\r\n if (date.getMonth() == holiday.getMonth() &&\r\n date.getDate() == holiday.getDate() &&\r\n (date.getFullYear() == holiday.getFullYear() ||\r\n holiday.getFullYear() <= 2000)) // Holidays with same date every year\r\n return true;\r\n }\r\n\r\n return false;\r\n },\r\n getFavoriteInstanceCount: function (presId, onComplete) {\r\n var request = new Librarian.Request({\r\n url: Librarian.path.getMethodUrl(\"getvpic\") + \"&pid=\" + presId + \"&out=ujson\",\r\n onSuccess: onComplete,\r\n onFailure: Librarian.Utils.onFailure\r\n });\r\n request.send();\r\n return request;\r\n },\r\n reloadThumbnails: function () {\r\n // Reload the tilelist thumbnails\r\n if ((typeof tileList != \"undefined\") && (tileList != null))\r\n tileList.reloadThumbnails();\r\n if ((typeof tileList2 != \"undefined\") && (tileList2 != null))\r\n tileList2.reloadThumbnails();\r\n if ((typeof sectionList != \"undefined\") && (sectionList != null))\r\n sectionList.reloadThumbnails();\r\n if (Librarian.cartWindow && Librarian.cartWindow.cartList != null)\r\n Librarian.cartWindow.cartList.reloadThumbnails();\r\n },\r\n updateAllCheckboxes: function () {\r\n if ((typeof tileList != \"undefined\") && (tileList != null))\r\n Librarian.Utils.updateCheckboxes(tileList.getItemStyle());\r\n if ((typeof fileList != \"undefined\") && (fileList != null))\r\n Librarian.ListView.updateCartCheckBoxes.bind(fileList)();\r\n if (typeof Library.updateCheckboxes == \"function\")\r\n Library.updateCheckboxes();\r\n if (Librarian.SearchResult != null && Librarian.SearchResult.resultViews != null) {\r\n Array.each(Librarian.SearchResult.resultViews, function (view) {\r\n view.updateCartCheckBoxes();\r\n });\r\n }\r\n },\r\n updateCheckboxes: function (styleName) {\r\n var elements = $$('.' + styleName),\r\n fromCart = styleName.contains(\"-cart\");\r\n\r\n for (var i = 0; i < elements.length; i++) {\r\n if ((elements[i].enabled == false) || !elements[i].tileItem.cartCheckEl || (elements[i].tileItem.cartCheckEl.get(\"enabled\") == \"false\") || !Librarian.userCart)\r\n continue;\r\n\r\n if (Librarian.userCart.isInCart(elements[i].tileItem.data, !fromCart)) {\r\n elements[i].tileItem.checked = true;\r\n\r\n if (Librarian.tileList.enableHoverMenu)\r\n elements[i].tileItem.cartCheckEl.show();\r\n else\r\n elements[i].tileItem.cartCheckEl.set(\"checked\", true);\r\n }\r\n else {\r\n elements[i].tileItem.checked = false;\r\n\r\n if (Librarian.tileList.enableHoverMenu)\r\n elements[i].tileItem.cartCheckEl.hide();\r\n else\r\n elements[i].tileItem.cartCheckEl.set(\"checked\", false);\r\n }\r\n }\r\n },\r\n setButtonState: function (itemEl, wrapperEl, disable) {\r\n if (!itemEl)\r\n return;\r\n\r\n if (disable) {\r\n if (itemEl.src) {\r\n // This item is already grayed out.\r\n if (itemEl.src.contains(\"_gray\"))\r\n return;\r\n // There are no \"checked gray\" images\r\n if (itemEl.src.contains(\"_checked\"))\r\n return;\r\n\r\n // Get the index of the last . so we can get the extension\r\n var extIndex = itemEl.src.lastIndexOf('.');\r\n // Get the extension from the src\r\n var ext = itemEl.src.substring(extIndex + 1, itemEl.src.length);\r\n\r\n // If we don't have a stored original src, store the current src.\r\n if ((itemEl.src_orig == undefined) || (itemEl.src_orig == null))\r\n itemEl.src_orig = itemEl.src;\r\n\r\n // Change the src to the gray image\r\n itemEl.src = itemEl.src.substring(0, extIndex) + \"_gray.\" + ext;\r\n }\r\n\r\n itemEl.addClass(\"disabled\");\r\n if (wrapperEl)\r\n wrapperEl.addClass(\"disabled\");\r\n }\r\n else {\r\n // Only switch everything back if there is an original src to switch back to\r\n if ((itemEl.src_orig != undefined) && (itemEl.src_orig != null))\r\n itemEl.src = itemEl.src_orig;\r\n\r\n itemEl.removeClass(\"disabled\");\r\n if (wrapperEl)\r\n wrapperEl.removeClass(\"disabled\");\r\n }\r\n },\r\n setButtonDisabled: function (buttonEl, disable) {\r\n Librarian.Utils.setElementDisabled(buttonEl, disable);\r\n },\r\n setElementDisabled: function (itemEl, disable, recursive) {\r\n if (!itemEl)\r\n return;\r\n if ((typeof disable == \"undefined\") || (disable == null))\r\n disable = true;\r\n\r\n itemEl.disabled = disable;\r\n\r\n if (disable)\r\n itemEl.addClass(\"disabled\");\r\n else\r\n itemEl.removeClass(\"disabled\");\r\n\r\n if (recursive) {\r\n var children = itemEl.getElements(\"*\");\r\n children.forEach(function (childEl) {\r\n Librarian.Utils.setElementDisabled(childEl, disable);\r\n });\r\n }\r\n },\r\n setTreeFileDisplay: function (show) {\r\n Librarian.Utils.runOnAllTrees((show ? \"show\" : \"hide\") + \"Files\");\r\n },\r\n unselectAllTrees: function () {\r\n Librarian.Utils.runOnAllTrees(\"unselect\");\r\n Librarian.Utils.unselectAllWorkspaces();\r\n },\r\n runOnAllTrees: function (funcName) {\r\n var trees = Librarian.treeViews;\r\n for (var treeName in trees) {\r\n if (!trees.hasOwnProperty(treeName))\r\n continue;\r\n\r\n var tree = trees[treeName];\r\n if (tree != null) {\r\n if (typeof funcName == \"function\")\r\n funcName(tree);\r\n else if (typeof funcName == \"string\")\r\n tree[funcName]();\r\n }\r\n }\r\n },\r\n unselectAllWorkspaces: function () {\r\n $$(\".request-tree-label-selected\").removeClass(\"request-tree-label-selected\");\r\n $$(\".upload-tree-label-selected\").removeClass(\"upload-tree-label-selected\");\r\n $$(\".proc-tree-label-selected\").removeClass(\"proc-tree-label-selected\");\r\n $$(\".myFilesLinkLabel-tree-label-selected\").removeClass(\"myFilesLinkLabel-tree-label-selected\");\r\n $$(\".bookmark-tree-label-selected\").removeClass(\"bookmark-tree-label-selected\");\r\n },\r\n // Load the category given in the path\r\n loadCategoryByPath: function (path) {\r\n // Try selecting the path in the tree, if that fails, loads the category\r\n Librarian.Utils.selectTreeNodeByPath(treeView, path, null, true, function () {\r\n Librarian.Utils.getCatFromPath(path, function (data) {\r\n Library.loadItemView(Object.toLowerKeys(data), data.name, data.description, data.type, tileList);\r\n });\r\n });\r\n },\r\n // Should be called load folder by name, doesn't accept a path\r\n loadFolderByPath: function (namedPath, catType, tree) {\r\n if ((typeof catType == \"undefined\") || (catType == null))\r\n catType = Librarian.catType.file;\r\n if ((typeof tree == \"undefined\") || (tree == null)) {\r\n if (typeof Library.getTreeByType == \"function\")\r\n tree = Library.getTreeByType(catType);\r\n else\r\n tree = treeView;\r\n }\r\n\r\n Librarian.Utils.getPath({ path: namedPath, type: (catType || Librarian.catType.file) }, function (path) {\r\n if (path == null) {\r\n Librarian.Utils.error(\"Could not find path in library:\\n\" + namedPath);\r\n return;\r\n }\r\n\r\n Librarian.Utils.selectTreeNodeByPath(tree, path);\r\n });\r\n },\r\n selectTreeNodeByPath: function (tree, path, start, useName, onFailure) {\r\n if (!tree)\r\n return;\r\n if ((typeof path == \"undefined\") || (path == null) || (path.length == 0))\r\n return;\r\n if ((typeof start == \"undefined\") || (start == null))\r\n start = true;\r\n if ((typeof useName == \"undefined\") || (useName == null))\r\n useName = false;\r\n\r\n Librarian.treeView.hasSelectionFinished = false;\r\n\r\n // If the tree isn't loaded\r\n if (!tree.loaded) {\r\n tree.recurseData = {\r\n path: path,\r\n start: start,\r\n useName: useName\r\n };\r\n\r\n // Wait until it IS loaded\r\n Librarian.Utils.runFunctionOnTreeEvent(tree, \"load\", function () {\r\n // If there is a root is it hasn't loaded\r\n if (this.root && !this.root.isLoaded()) {\r\n // Wait until IT is loaded\r\n Librarian.Utils.runFunctionOnTreeEvent(this.root, \"load\", function () {\r\n // And then finally run this function\r\n Librarian.Utils.selectTreeNodeByPath(this.tree, this.tree.recurseData.path, this.tree.recurseData.start, this.tree.recurseData.useName, onFailure);\r\n });\r\n }\r\n // Otherwise, try running the function now\r\n else\r\n Librarian.Utils.selectTreeNodeByPath(this, this.recurseData.path, this.recurseData.start, this.recurseData.useName, onFailure);\r\n });\r\n return;\r\n }\r\n else if (!tree.root.isOpen())\r\n tree.root.toggle(true);\r\n\r\n // Split the string into a list\r\n if (typeof path == \"string\")\r\n path = path.split('/');\r\n\r\n for (var i = 0; i < path.length; i++) {\r\n // Get the selected node in the tree\r\n var parent = tree.getSelected();\r\n // If there is no selected node, try the root\r\n if (!parent || start)\r\n parent = tree.root;\r\n // In deep links the \"parent\" isn't really a node so we need to get the first real node\r\n if (!parent.data)\r\n parent = parent.children[0];\r\n\r\n var parentData = null,\r\n // Default to assuming this is a file\r\n treeData = \"fileid\";\r\n // But if we're told to use names, check that instead\r\n if (useName)\r\n parentData = parent.property.name;\r\n else {\r\n // If it starts with a C, though, it's a category\r\n if (path[i].startsWith(\"C\")) {\r\n // Trim off the C\r\n path[i] = path[i].substring(1);\r\n // And store the catid property as the key\r\n treeData = \"catid\";\r\n }\r\n // If it starts with a E, though, it's an event\r\n else if (path[i].startsWith(\"E\")) {\r\n // Trim off the C\r\n path[i] = path[i].substring(1);\r\n // And store the eventid property as the key\r\n treeData = \"eventid\";\r\n }\r\n\r\n parentData = parent.data[treeData];\r\n }\r\n\r\n // Check this node to see if it's the one we're looking for\r\n if (parentData == path[i]) {\r\n if (parent != tree.getSelected()) {\r\n // If this isn't the last item in the path\r\n if (i != (path.length - 1)) {\r\n // Chop this item off the beginning of the path list\r\n parent.path = path.slice(i + 1);\r\n parent.useName = useName;\r\n // Set open to false so that we force it open\r\n parent.state.open = false;\r\n Librarian.Utils.handleTreeToggleAndLoad(parent, function () {\r\n this.tree.select(this);\r\n\r\n // Once the node is loaded and open, keep searching if there\r\n // are things left to search for\r\n if (this.path.length > 0)\r\n Librarian.Utils.selectTreeNodeByPath(this.tree, this.path, false, this.useName, onFailure);\r\n });\r\n\r\n // Don't continue. Regardless of whether the parent is already loaded or open\r\n // the inner function will be called, causing a recursive call to this function.\r\n // If we continue, we will end up with two parallel recursive loading branches\r\n return;\r\n }\r\n else {\r\n // Only let the PageHeader load if this is the last item in the path\r\n Librarian.treeView.hasSelectionFinished = true;\r\n tree.select(parent);\r\n }\r\n }\r\n\r\n // If this is the end of the path,\r\n // return here so the \"Cannot find this item\" message isn't displayed\r\n if (i == (path.length - 1))\r\n return;\r\n else\r\n continue;\r\n }\r\n\r\n // Get the children for this node\r\n var children = parent.getChildren();\r\n // If there aren't any, bail\r\n if (!children)\r\n return;\r\n\r\n // Check every child\r\n for (var j = 0; j < children.length; j++) {\r\n var childData = null;\r\n if (useName)\r\n childData = children[j].property.name;\r\n else\r\n childData = children[j].data[treeData];\r\n\r\n // If the id matches\r\n if (childData == path[i]) {\r\n // Only let the PageHeader load if this is the last item in the path\r\n if (i == (path.length - 1))\r\n Librarian.treeView.hasSelectionFinished = true;\r\n\r\n // If we're checking file data and this is actually a file, select it\r\n if ((treeData != \"catid\") && (typeof children[j][treeData] != \"undefined\")) {\r\n tree.select(children[j]);\r\n\r\n // If this is the end of the path,\r\n // return here so the \"Cannot find this item\" message isn't displayed\r\n if (i == (path.length - 1))\r\n return;\r\n else\r\n break;\r\n }\r\n\r\n // Chop this item off the beginning of the path list\r\n children[j].path = path.slice(i + 1);\r\n children[j].useName = useName;\r\n // Set open to false so that we force it open\r\n children[j].state.open = false;\r\n Librarian.Utils.handleTreeToggleAndLoad(children[j], function () {\r\n this.tree.select(this);\r\n\r\n // Once the node is loaded and open, run keep searching if there\r\n // are things left to search for\r\n if (this.path.length > 0)\r\n Librarian.Utils.selectTreeNodeByPath(this.tree, this.path, false, this.useName, onFailure);\r\n });\r\n\r\n // Don't continue. Regardless of whether the node is already loaded or open\r\n // the inner function will be called, causing a recursive call to this function.\r\n // If we continue, we will end up with two parallel recursive loading branches\r\n return;\r\n }\r\n }\r\n }\r\n\r\n // Selection has finished, we just didn't find anything\r\n Librarian.treeView.hasSelectionFinished = true;\r\n // If we have gotten here, the thing we're looking for doesn't exist in the tree\r\n if (typeof onFailure == \"function\")\r\n onFailure();\r\n else\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cantfindintree\"));\r\n tree.unselect();\r\n\r\n // Load the home page as the default if we can't find this thing in the tree\r\n if (typeof Library.showHomePage == \"function\")\r\n Library.showHomePage();\r\n else if (typeof showHomePage == \"function\")\r\n showHomePage();\r\n },\r\n handleTreeToggleAndLoad: function (node, fn) {\r\n if (!node)\r\n return;\r\n if (typeof fn != \"function\")\r\n return;\r\n\r\n // If the node isn't loaded, load it, if it's a category\r\n else if (!node.isLoaded() && node.data && (node.data.fileid == null)) {\r\n Librarian.Utils.runFunctionOnTreeEvent(node, \"load\", function () {\r\n // Now that it's loaded, open it\r\n Librarian.Utils.handleTreeToggleAndLoad(this, fn);\r\n });\r\n\r\n if (!node.$loading) {\r\n node.load();\r\n }\r\n }\r\n // If it is loaded, just make sure it's opened (if it can be)\r\n else if (!node.isOpen() && node.hasChildren()) {\r\n Librarian.Utils.runFunctionOnTreeEvent(node, \"toggle\", fn);\r\n node.toggle(true);\r\n }\r\n else\r\n fn.bind(node)();\r\n },\r\n runFunctionOnTreeEvent: function (node, eventName, fn) {\r\n if (!node)\r\n return;\r\n if (typeof eventName != \"string\")\r\n return;\r\n if (typeof fn != \"function\")\r\n return;\r\n\r\n function onEvent() {\r\n node.removeEvent(eventName, onEvent);\r\n fn.bind(node)();\r\n }\r\n\r\n node.addEvent(eventName, onEvent);\r\n },\r\n setSelectValue: function (selectEl, values, predicate) {\r\n if ((typeof selectEl == \"undefined\") || (selectEl == null))\r\n return -1;\r\n if ((typeof values == \"undefined\") || (values == null))\r\n return -1;\r\n\r\n // Make sure values is an array so we can support multi-select selects\r\n if (!(values instanceof Array))\r\n values = [values];\r\n\r\n var found = false;\r\n // De-select every option before checking\r\n for (var i = 0; i < selectEl.options.length; i++) {\r\n selectEl.options[i].selected = false;\r\n\r\n // Check each value, if this isn't a multi-select it will return after the first found\r\n for (var j = values.length; j--;) {\r\n var value = values[j];\r\n if ((selectEl.options[i].value == value) && ((typeof predicate != \"function\") || predicate(selectEl.options[i]))) {\r\n if (!selectEl.multiple) {\r\n selectEl.selectedIndex = i;\r\n return i;\r\n }\r\n\r\n selectEl.options[i].selected = true;\r\n found = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return found || -1;\r\n },\r\n getSelectedItem: function (selectEl) {\r\n if ((typeof selectEl == \"undefined\") || (selectEl == null))\r\n return null;\r\n\r\n var selectedIndex = selectEl.selectedIndex;\r\n if ((selectedIndex < 0) || (selectedIndex >= selectEl.options.length))\r\n return null;\r\n\r\n return selectEl.options[selectedIndex];\r\n },\r\n getSelectedValue: function (selectEl) {\r\n if (!selectEl)\r\n return null;\r\n\r\n var multiple = selectEl.get(\"multiple\");\r\n if (multiple) {\r\n var values = [],\r\n options = selectEl.options;\r\n for (var i = options.length; i--;) {\r\n if (options[i].selected)\r\n values.push(options[i].value);\r\n }\r\n return values;\r\n }\r\n\r\n var itemEl = Librarian.Utils.getSelectedItem(selectEl);\r\n return itemEl ? itemEl.value : null;\r\n },\r\n setElementValue: function (elementEl, value) {\r\n if ((typeof elementEl == \"undefined\") || (elementEl == null))\r\n return;\r\n if ((typeof value == \"undefined\") || (value == null))\r\n return;\r\n\r\n if (elementEl.tagName == \"INPUT\") {\r\n if ((elementEl.type == \"checkbox\") || (elementEl.type == \"radio\")) {\r\n elementEl.set(\"checked\", (value === true) || ((value + '') === \"true\"));\r\n }\r\n else\r\n elementEl.value = value;\r\n }\r\n else if (elementEl.tagName == \"SELECT\")\r\n Librarian.Utils.setSelectValue(elementEl, value);\r\n else if (elementEl.tagName == \"TEXTAREA\") {\r\n // Make sure both of these are set so all browsers will recognize it\r\n elementEl.innerText = value;\r\n elementEl.value = value;\r\n }\r\n else\r\n elementEl.set(\"text\", value);\r\n },\r\n getElementValue: function (elementEl, getCheckValue, returnNullIfUncheck) {\r\n if ((typeof elementEl == \"undefined\") || (elementEl == null))\r\n return null;\r\n\r\n // Make sure IE8 isn't being stupid\r\n elementEl = $(elementEl);\r\n\r\n if (elementEl.tagName == \"INPUT\") {\r\n if (!getCheckValue && ((elementEl.type == \"checkbox\") || (elementEl.type == \"radio\"))) {\r\n return elementEl.get(\"checked\");\r\n }\r\n else {\r\n if (returnNullIfUncheck && (elementEl.type == \"checkbox\") || (elementEl.type == \"radio\")) {\r\n var isChecked = elementEl.get(\"checked\");\r\n return isChecked ? elementEl.value : null;\r\n }\r\n else {\r\n return elementEl.value;\r\n } \r\n }\r\n \r\n }\r\n else if (elementEl.tagName == \"SELECT\")\r\n return Librarian.Utils.getSelectedValue(elementEl);\r\n else if (elementEl.tagName == \"TEXTAREA\")\r\n return elementEl.value || elementEl.innerText;\r\n\r\n return elementEl.get(\"text\");\r\n },\r\n validateInputPattern: function(inputEl, ignoreEmpty) {\r\n var value = inputEl.value;\r\n if (!value && ignoreEmpty)\r\n return true;\r\n\r\n var pattern = inputEl.pattern;\r\n if (!pattern)\r\n return true;\r\n\r\n var regex = new RegExp(pattern);\r\n\r\n return regex.test(value);\r\n },\r\n fillSelect: function (selectEl, options, allowEmpty, clearFirst) {\r\n if (!selectEl)\r\n return;\r\n if ((typeof options == \"undefined\") || (options == null))\r\n return;\r\n if ((typeof allowEmpty == \"undefined\") || (allowEmpty == null))\r\n allowEmpty = false;\r\n if ((typeof clearFirst == \"undefined\") || (clearFirst == null))\r\n clearFirst = false;\r\n\r\n if (clearFirst) {\r\n selectEl.empty();\r\n selectEl.options.length = 0;\r\n }\r\n\r\n for (var i = 0; i < options.length; i++) {\r\n var name,\r\n value,\r\n disabled = false;\r\n\r\n if (typeOf(options[i]) == \"array\") {\r\n name = (options[i][0] || '').trim();\r\n value = (options[i][1] || '').trim();\r\n }\r\n else if (typeOf(options[i]) == \"object\") {\r\n name = options[i].name;\r\n value = options[i].id || name;\r\n disabled = !!options[i].disabled;\r\n }\r\n else {\r\n name = options[i];\r\n value = options[i];\r\n }\r\n\r\n if (!allowEmpty && (name.length == 0) && (value.length == 0))\r\n continue;\r\n\r\n var optionEl = new Option(name, value);\r\n if (disabled)\r\n optionEl.disabled = disabled;\r\n selectEl.options.add(optionEl);\r\n }\r\n },\r\n limitValueLength: function (length) {\r\n if (this.value.length > length) {\r\n Librarian.Utils.error(Librarian.Lang.getArgString(\"max_length\", [length]));\r\n // Cancel keyhit\r\n this.value = this.value.substring(0, length);\r\n }\r\n },\r\n setValueLengthLabel: function (countLimit, countContainerId) {\r\n if ((typeof countLimit != \"number\") || (typeof countContainerId != \"string\"))\r\n return;\r\n\r\n var count = (this.value || '').length,\r\n remaining = countLimit - count;\r\n\r\n Librarian.Utils.setElementValue($(countContainerId), remaining);\r\n },\r\n createLabeledInput: function (parentEl, id, type, name, value, label, checked, className, data, onClick, labelFunc) {\r\n if (!parentEl)\r\n return null;\r\n\r\n var contEl = new Element(\"div\", {\r\n \"class\": className + \"-container\"\r\n }).injectInside(parentEl);\r\n\r\n var labelEl = new Element(\"label\", {\r\n \"class\": className + \"-label\",\r\n \"for\": id\r\n }).injectInside(contEl);\r\n\r\n var childEl = new Element(\"input[type=\" + type + \"]\", {\r\n \"id\": id,\r\n \"class\": className,\r\n \"name\": name,\r\n \"value\": value,\r\n \"checked\": (checked ? \"checked\" : '')\r\n }).injectInside(labelEl);\r\n\r\n if (typeof onClick == \"function\")\r\n childEl.addOnClick(onClick, childEl);\r\n\r\n // Set extra data if there is any\r\n if (data) {\r\n for (var key in data) {\r\n if (data.hasOwnProperty(key))\r\n childEl.set(key, data[key]);\r\n }\r\n }\r\n\r\n var labelNodeEl;\r\n if (labelFunc) {\r\n labelNodeEl = labelFunc(name, value, label);\r\n }\r\n else {\r\n labelNodeEl = document.createTextNode(label);\r\n }\r\n\r\n labelEl.appendChild(labelNodeEl);\r\n\r\n return contEl;\r\n },\r\n clearSearchRequests: function () {\r\n if (Librarian.contentLoader && Librarian.contentLoader.lastRequest) {\r\n Librarian.contentLoader.lastRequest.cancel();\r\n Librarian.contentLoader.lastRequest = null;\r\n }\r\n\r\n if (Librarian.lastSearch) {\r\n Librarian.lastSearch.cancel();\r\n Librarian.lastSearch.destroy();\r\n Librarian.lastSearch = null;\r\n }\r\n },\r\n clearRequests: function () {\r\n if (Librarian.myProcView != null) {\r\n Librarian.myProcView.enabled = false;\r\n\r\n if (Librarian.myProcView.request) {\r\n Librarian.myProcView.request.cancel();\r\n Librarian.myProcView.request = null;\r\n }\r\n\r\n // Don't stop this request, but stop it from reloading the table when it finishes.\r\n if (Librarian.myProcView.deleteRequest)\r\n Librarian.myProcView.deleteRequest.onSuccess = function () { };\r\n }\r\n\r\n if (Librarian.myInProgProcView != null) {\r\n Librarian.myInProgProcView.enabled = false;\r\n\r\n if (Librarian.myInProgProcView.request) {\r\n Librarian.myInProgProcView.request.cancel();\r\n Librarian.myInProgProcView.request = null;\r\n }\r\n }\r\n },\r\n clearFocus: function () {\r\n Librarian.Utils.runOnAllTrees(function (tree) {\r\n if (tree != null && tree.keyNav)\r\n tree.keyNav.detach();\r\n });\r\n },\r\n checkString: function (string) {\r\n for (var i = 0; i < string.length; i++) {\r\n if (Librarian.path.badChars.contains(string.charAt(i)))\r\n return false;\r\n }\r\n\r\n return true;\r\n },\r\n scrubString: function (string, replacement) {\r\n replacement = replacement || '_';\r\n string = string || '';\r\n\r\n for (var i = 0; i < string.length; i++) {\r\n if (Librarian.path.badChars.contains(string.charAt(i)))\r\n string = string.setCharAt(i, replacement);\r\n }\r\n\r\n return string;\r\n },\r\n undecorateFileName: function (name) {\r\n if (!name || !name.contains('@'))\r\n return name;\r\n\r\n // Get the index of the @\r\n var atIndex = name.indexOf('@'),\r\n // Find the _ that separates the e-mail from the file name\r\n underscoreIndex = name.indexOf('_', atIndex);\r\n // If it exists, chop everything up to that point\r\n if (underscoreIndex >= 0)\r\n name = name.substring(underscoreIndex + 1, name.length);\r\n\r\n return name;\r\n },\r\n loadCustomXML: function (path) {\r\n var xhttp;\r\n\r\n if (window.XMLHttpRequest)\r\n xhttp = new XMLHttpRequest();\r\n else\r\n xhttp = new ActiveXObject(\"Microsoft.XMLHTTP\");\r\n\r\n xhttp.open(\"GET\", path, false);\r\n xhttp.send();\r\n\r\n if (xhttp.status != 200)\r\n return null;\r\n\r\n var xml = xhttp.responseXML;\r\n\r\n xhttp = null;\r\n\r\n // CLN-840 - Workaround for IE10 and higher no longer having direct XPath support\r\n // This forces the use of the ActiveX XML DOM which still supports the needed methods\r\n // CLN-1470 - Workaround for Chrome having the same issue as newer IE\r\n if ((Browser.ie && (Browser.version > 9)))\r\n xml = Librarian.Utils.getXMLDoc(Librarian.Utils.getXMLText(xml));\r\n\r\n return xml;\r\n },\r\n getXMLDoc: function (xmlText) {\r\n var doc;\r\n\r\n if (window.DOMParser && !Browser.ie) {\r\n var parser = new DOMParser();\r\n doc = parser.parseFromString(xmlText, \"text/xml\");\r\n }\r\n else {\r\n doc = new ActiveXObject(\"Microsoft.XMLDOM\");\r\n doc.async = \"false\";\r\n doc.preserveWhiteSpace = true;\r\n doc.loadXML(xmlText);\r\n }\r\n return doc;\r\n },\r\n createXMLDoc: function (rootName) {\r\n return Librarian.Utils.getXMLDoc('<' + rootName + \">');\r\n },\r\n getXMLText: function (xmlDoc) {\r\n var xml = xmlDoc.xml;\r\n\r\n // If there is no \"xml\" element, we have to serialize it ourselves\r\n if (xml == undefined) {\r\n // Make sure there IS a serializer.\r\n if (XMLSerializer) {\r\n // And get the xml string from the document\r\n var serializer = new XMLSerializer();\r\n xml = serializer.serializeToString(xmlDoc);\r\n\r\n serializer = null;\r\n }\r\n }\r\n\r\n return xml;\r\n },\r\n getXMLNodeText: function (nodeEl) {\r\n if (!nodeEl)\r\n return null;\r\n\r\n var text = nodeEl.text;\r\n if (typeof text != \"string\")\r\n text = nodeEl.textContent;\r\n if (typeof text != \"string\") {\r\n if (!nodeEl.get)\r\n return null;\r\n text = nodeEl.get(\"text\");\r\n }\r\n\r\n return text;\r\n },\r\n setXMLNodeText: function (nodeEl, text) {\r\n if (!nodeEl)\r\n return;\r\n\r\n if (!nodeEl.text) {\r\n if (nodeEl.set)\r\n nodeEl.set(\"text\", text);\r\n }\r\n else\r\n nodeEl.text = text;\r\n },\r\n getAttributeXMLNode: function (xmlDoc, attributeType, name, value) {\r\n var attribEl = xmlDoc.createElement(attributeType),\r\n nameEl = attribEl.appendChild(xmlDoc.createElement(\"Name\")),\r\n valueEl = attribEl.appendChild(xmlDoc.createElement(\"Value\"));\r\n\r\n nameEl.appendChild(xmlDoc.createTextNode(name));\r\n valueEl.appendChild(xmlDoc.createTextNode(value));\r\n\r\n return attribEl;\r\n },\r\n cloneXMLNode: function (xmlDoc, nodeEl, value) {\r\n var clonedEl = xmlDoc.createElement(nodeEl.nodeName);\r\n if ((typeof value != \"undefined\") && (value != null))\r\n clonedEl.appendChild(xmlDoc.createTextNode(value));\r\n\r\n for (var k = nodeEl.attributes.length; k--;)\r\n clonedEl.setAttribute(nodeEl.attributes[k].name, nodeEl.attributes[k].text || nodeEl.attributes[k].value);\r\n\r\n for (var l = nodeEl.childNodes.length; l--;) {\r\n if (nodeEl.childNodes[l].nodeName == \"#text\") {\r\n var nodeText = Librarian.Utils.getXMLNodeText(nodeEl.childNodes[l]);\r\n if (nodeText != null)\r\n clonedEl.appendChild(xmlDoc.createTextNode(nodeText));\r\n }\r\n else\r\n clonedEl.appendChild(Librarian.Utils.cloneXMLNode(xmlDoc, nodeEl.childNodes[l]));\r\n }\r\n\r\n return clonedEl;\r\n },\r\n cloneXMLDoc: function (xmlDoc) {\r\n var xml = Librarian.Utils.getXMLText(xmlDoc),\r\n newXMLDoc;\r\n\r\n if (window.DOMParser && !Browser.ie) {\r\n var parser = new DOMParser();\r\n newXMLDoc = parser.parseFromString(xml, \"text/xml\");\r\n\r\n parser = null;\r\n }\r\n // Internet Explorer\r\n else {\r\n newXMLDoc = new ActiveXObject(\"Microsoft.XMLDOM\");\r\n newXMLDoc.async = \"false\";\r\n newXMLDoc.loadXML(xml);\r\n }\r\n\r\n return newXMLDoc;\r\n },\r\n doesXMLHaveNode: function (nodeEl, nodeName) {\r\n return nodeEl.getElementsByTagName(nodeName).length > 0;\r\n },\r\n getOrAddXMLNode: function(parentEl, name) {\r\n var nodeEl = Librarian.Utils.getXMLNode(parentEl, name);\r\n if (!nodeEl)\r\n nodeEl = Librarian.Utils.addXMLNode(parentEl, name);\r\n\r\n return nodeEl;\r\n },\r\n getXMLNode: function(parentEl, name) {\r\n return parentEl.getElementsByTagName(name)[0];\r\n },\r\n addXMLNode: function(parentEl, name, value) {\r\n var xmlDoc;\r\n if (parentEl instanceof XMLDocument) {\r\n xmlDoc = parentEl;\r\n parentEl = xmlDoc.documentElement;\r\n }\r\n else\r\n xmlDoc = parentEl.getDocument();\r\n\r\n var nodeEl = xmlDoc.createElement(name);\r\n parentEl.appendChild(nodeEl);\r\n\r\n if (value != null)\r\n nodeEl.set(\"text\", value);\r\n\r\n return nodeEl;\r\n },\r\n\r\n // Adapted from https://davidwalsh.name/convert-xml-json\r\n // by David Walsh\r\n xmlToJson: function (xml) {\r\n var obj = {};\r\n\r\n if (xml.nodeType == 1) { // element\r\n if (xml.attributes.length > 0) {\r\n obj[\"_attributes\"] = {};\r\n for (var j = 0; j < xml.attributes.length; j++) {\r\n var attribute = xml.attributes.item(j);\r\n obj[\"_attributes\"][attribute.nodeName] = attribute.nodeValue;\r\n }\r\n }\r\n }\r\n else if (xml.nodeType == 3) { // text\r\n obj = xml.nodeValue;\r\n }\r\n\r\n var elements = Array.from(xml.childNodes).filter(function (node) {\r\n return node.nodeType == 1;\r\n });\r\n\r\n if (elements.length > 0) {\r\n for (var i = 0; i < elements.length; i++) {\r\n var item = elements[i],\r\n nodeName = item.nodeName;\r\n\r\n if (obj[nodeName] == null) {\r\n // First child with this name\r\n obj[nodeName] = this.xmlToJson(item);\r\n } else {\r\n // Create an array of children with the same name\r\n if (obj[nodeName].push == null) {\r\n var old = obj[nodeName];\r\n obj[nodeName] = [];\r\n obj[nodeName].push(old);\r\n }\r\n\r\n obj[nodeName].push(this.xmlToJson(item));\r\n }\r\n }\r\n }\r\n else\r\n obj = xml.textContent;\r\n\r\n return obj;\r\n },\r\n renderContactName: function (data /*, row, colmod*/) {\r\n if (data.isgroup)\r\n return data.groupname || data.name;\r\n\r\n var name = '';\r\n\r\n if (data.firstname)\r\n name = data.firstname;\r\n\r\n if (data.lastname) {\r\n if (name.length > 0)\r\n name += \" \";\r\n\r\n name += data.lastname;\r\n }\r\n\r\n return name;\r\n },\r\n getContactNameClass: function(data) {\r\n if (data.isgroup)\r\n return \"group-name\";\r\n else\r\n return \"contact-name\";\r\n },\r\n isValidEmailAddress: function(email) {\r\n // text@text.text\r\n var regex = /[^<>()\\s]+@[^<>()\\s]+\\.[^<>()\\s]+/;\r\n\r\n return regex.test(email);\r\n },\r\n getLocalTimezoneName: function () {\r\n var dateString = new Date().toString();\r\n\r\n // Parse the timezone from the end of the date string\r\n // This works for Chrome and Firefox, but not IE\r\n var matches = /\\((.*)\\)/.exec(dateString);\r\n if (matches)\r\n return matches[1];\r\n\r\n return \"\";\r\n },\r\n getUTCDateValue: function (dateString, format) {\r\n var date = Librarian.Utils.extractDateFromString(dateString);\r\n if (!date || isNaN(date) || (date == \"Invalid Date\"))\r\n return null;\r\n\r\n date.increment(\"hour\", -date.getGMTOffset().toInt() / 100);\r\n\r\n return Librarian.Utils.getDateValue(date, format);\r\n },\r\n getDateValue: function (dateString, format) {\r\n var date = Librarian.Utils.extractDateFromString(dateString);\r\n if (typeof format != \"string\")\r\n format = \"%m/%d/%Y\";\r\n\r\n if (!date || isNaN(date) || (date == \"Invalid Date\"))\r\n date = null;\r\n else\r\n date = date.format(format);\r\n\r\n return date;\r\n },\r\n extractDateFromString: function (dateString) {\r\n if (dateString instanceof Date)\r\n return dateString;\r\n\r\n if (dateString) {\r\n // Make sure this is actually a string\r\n dateString = dateString + '';\r\n\r\n // Datestring cannot be parsed correctly if it uses \".+\" instead of \"+\"\r\n dateString = dateString.replace(\".+\", \"+\");\r\n\r\n if (dateString.contains(\"Date(\")) {\r\n var end = dateString.indexOf('-');\r\n if (end < 0)\r\n end = dateString.indexOf(')');\r\n\r\n return eval(\"new \" + dateString.slice(1, end) + \")\");\r\n }\r\n else {\r\n // Try to parse the date out as-is\r\n var date = Date.parse(dateString);\r\n // Newer browsers return a number from Date.parse\r\n // If that is the case, convert it to a date object\r\n if (typeof date == \"number\")\r\n date = new Date(date);\r\n // If that didn't work, it may be an ISO format in an older browser\r\n // The fromISO function will also use the native Date constructor parsing if the string isn't in ISO format\r\n if (isNaN(date))\r\n date = Date.fromISO(dateString);\r\n return date;\r\n }\r\n }\r\n\r\n return null;\r\n },\r\n setUpDatePicker: function (boxClass, boxId, iconId, parentId, onIconClick, options) {\r\n var picker = null;\r\n var dateFields = $$(\"input.\" + boxClass);\r\n if (dateFields.length > 0) {\r\n var defaultOptions = {\r\n timePicker: false,\r\n positionOffset: { x: 0, y: 0 },\r\n pickerClass: \"datepicker_vista\",\r\n useFadeInOut: false\r\n };\r\n\r\n picker = new Picker.Date(dateFields, Object.merge(defaultOptions, options));\r\n\r\n dateFields.each(function (el) {\r\n el.removeClass(boxClass);\r\n });\r\n\r\n var calendarIconEl = $(parentId + '_' + iconId) || $(iconId);\r\n if (calendarIconEl) {\r\n if ((typeof parentId == \"string\") && (parentId.length > 0))\r\n calendarIconEl.id = parentId + '_' + iconId;\r\n calendarIconEl.parentId = parentId;\r\n calendarIconEl.boxId = boxId;\r\n calendarIconEl.onIconClick = onIconClick;\r\n calendarIconEl.src = Librarian.path.getDefaultThemePath() + \"images/icons/calendar.gif\";\r\n calendarIconEl.addOnClick(function (e) {\r\n var evt = new Event(e);\r\n evt.stop();\r\n\r\n if (typeof this.onIconClick == \"function\")\r\n this.onIconClick();\r\n\r\n var itemEl = $(this.parentId + '_' + this.boxId) || $(this.boxId);\r\n if (itemEl && itemEl.isVisible())\r\n itemEl.focus();\r\n\r\n evt = null;\r\n });\r\n }\r\n }\r\n\r\n return picker;\r\n },\r\n setUpDatePicker2: function (boxEl, iconEl, onIconClick, options) {\r\n var defaultOptions = {\r\n timePicker: false,\r\n positionOffset: { x: 0, y: 0 },\r\n pickerClass: \"datepicker_vista\",\r\n useFadeInOut: false,\r\n blockKeydown: false,\r\n };\r\n\r\n var picker = new Picker.Date(boxEl, Object.merge(defaultOptions, options));\r\n\r\n if (iconEl) {\r\n iconEl.boxEl = boxEl;\r\n iconEl.onIconClick = onIconClick;\r\n iconEl.addOnClick(function () {\r\n if (typeof this.onIconClick == \"function\")\r\n this.onIconClick();\r\n\r\n if (this.boxEl)\r\n this.boxEl.focus();\r\n\r\n return false;\r\n });\r\n }\r\n\r\n return picker;\r\n },\r\n progressBar: function (target, width, height, colors, leftValue, totalValue, display) {\r\n var targetEl = $(target);\r\n if (!targetEl)\r\n return;\r\n\r\n // Clear out the target\r\n targetEl.empty();\r\n\r\n // Make sure these are valid boolean values\r\n display.percent = !!display.percent;\r\n display.lowerbound = !!display.lowerbound;\r\n display.upperbound = !!display.upperbound;\r\n display.leftvalue = !!display.leftvalue;\r\n display.rightvalue = !!display.rightvalue;\r\n\r\n var percent = Math.min((leftValue / totalValue), 1),\r\n leftWidth = percent * width,\r\n rightWidth = width - leftWidth,\r\n\r\n // Use a table to keep the correct layout\r\n tableEl = new Element(\"table\"),\r\n bodyEl = new Element(\"tbody\"),\r\n rowEl = new Element(\"tr\"),\r\n leftColEl = new Element(\"td\"),\r\n rightColEl = new Element(\"td\"),\r\n percentColEl;\r\n\r\n // Create the left portion and fill it, but only if it will actually take up some space\r\n if (leftWidth > 0) {\r\n leftColEl.width = leftColEl.style.width = leftWidth + \"px\";\r\n leftColEl.height = leftColEl.style.height = height + \"px\";\r\n\r\n // Make sure the color exists before trying to use it\r\n if (colors.leftBackground != undefined)\r\n leftColEl.style.backgroundColor = colors.leftBackground;\r\n\r\n rowEl.appendChild(leftColEl);\r\n }\r\n\r\n // Create the right portion and fill it, but only if it will actually take up some space\r\n if (rightWidth > 0) {\r\n rightColEl.width = rightColEl.style.width = rightWidth + \"px\";\r\n rightColEl.height = rightColEl.style.height = height + \"px\";\r\n\r\n // Make sure the color exists before trying to use it\r\n if (colors.rightBackground != undefined)\r\n rightColEl.style.backgroundColor = colors.rightBackground;\r\n\r\n rowEl.appendChild(rightColEl);\r\n }\r\n\r\n bodyEl.appendChild(rowEl);\r\n\r\n // Show the current value on the left and the remaining value on the right\r\n if (display.rightvalue || display.leftvalue) {\r\n if (display.leftvalue)\r\n leftColEl.set(\"text\", leftValue);\r\n\r\n leftColEl.align = \"center\";\r\n leftColEl.style.color = colors.leftValue;\r\n\r\n if (display.rightvalue)\r\n rightColEl.set(\"text\", totalValue - leftValue);\r\n\r\n rightColEl.align = \"center\";\r\n rightColEl.style.color = colors.rightValue;\r\n }\r\n\r\n // Show 0 on the left and the total value on the right and the percent in the middle\r\n if (display.lowerbound || display.upperbound || display.percent) {\r\n var valueTableEl = new Element(\"table\"),\r\n valueBodyEl = new Element(\"tbody\"),\r\n valueRowEl = new Element(\"tr\"),\r\n colEl = new Element(\"td\");\r\n leftColEl = new Element(\"td\");\r\n rightColEl = new Element(\"td\");\r\n percentColEl = new Element(\"td\");\r\n rowEl = new Element(\"tr\");\r\n\r\n valueTableEl.width = \"100%\";\r\n colEl.colSpan = '2';\r\n\r\n // Set up the new columns\r\n if (display.lowerbound)\r\n leftColEl.set(\"text\", 0);\r\n\r\n leftColEl.width = (.4 * width);\r\n\r\n if (display.upperbound)\r\n rightColEl.set(\"text\", totalValue);\r\n rightColEl.width = (.4 * width);\r\n rightColEl.align = \"right\";\r\n\r\n // If we're showing the percent, add that in the middle\r\n if (display.percent)\r\n percentColEl.set(\"text\", Math.ceil(percent * 100) + '%');\r\n\r\n // Always add the space for it, though, so the layout is consistent\r\n percentColEl.align = \"center\";\r\n percentColEl.width = 40;\r\n\r\n // Add it all to the table now\r\n valueRowEl.appendChild(leftColEl);\r\n valueRowEl.appendChild(percentColEl);\r\n valueRowEl.appendChild(rightColEl);\r\n valueBodyEl.appendChild(valueRowEl);\r\n valueTableEl.appendChild(valueBodyEl);\r\n colEl.appendChild(valueTableEl);\r\n rowEl.appendChild(colEl);\r\n bodyEl.appendChild(rowEl);\r\n }\r\n\r\n // Add everything to the table and add the table to the target\r\n tableEl.appendChild(bodyEl);\r\n targetEl.appendChild(tableEl);\r\n },\r\n prepareItemData: function (data, index, parentData, count, totalIndex) {\r\n var ext = Librarian.Utils.getExtensionFromData(data);\r\n data.ext = ext;\r\n\r\n // If there is no fileid provided, default to 0\r\n if (data.fileid == undefined)\r\n data.fileid = 0;\r\n // If there is no presid provided, default to 0\r\n if (data.presid == undefined)\r\n data.presid = 0;\r\n // If there is no groupid provided, default to 0\r\n if (data.groupid == undefined)\r\n data.groupid = 0;\r\n // If there is no slideid provided, default to 0\r\n if (data.slideid == undefined)\r\n data.slideid = 0;\r\n\r\n // If there is parent data\r\n if (parentData) {\r\n // and it provides the fileid, store it.\r\n if (parentData.fileid > data.fileid)\r\n data.fileid = parentData.fileid;\r\n // and it provides the slideid, store it.\r\n if (parentData.slideid > data.slideid)\r\n data.slideid = parentData.slideid;\r\n // and it provides the groupid, store it.\r\n if (parentData.groupid > data.groupid)\r\n data.groupid = parentData.groupid;\r\n // and it provides the presid, store it.\r\n if (parentData.presid > data.presid)\r\n data.presid = parentData.presid;\r\n\r\n // Pull the file type extension out from it if the child\r\n // doesn't have this information.\r\n if (data.filetypeextension == undefined)\r\n data.filetypeextension = parentData.filetypeextension;\r\n // Pull the name out from it if the child\r\n // doesn't have a name.\r\n if (data.name == undefined)\r\n data.name = parentData.name;\r\n // If this is a group, save the group name as the name of this item\r\n if ((data.groupid > 0) && parentData.name)\r\n data.name = parentData.name;\r\n // If the child doesn't have a slidecount, pull it from\r\n // the length of the list of items.\r\n if (isNaN(data.slidecount)) {\r\n if (!isNaN(parentData.pagecount) && (parentData.pagecount > 0))\r\n data.slidecount = parentData.pagecount;\r\n else if (!isNaN(data.pagecount) && (data.pagecount > 0) && (data.presid < 0))\r\n data.slidecount = data.pagecount;\r\n // Items that are pretending to have slides should have their slidecount be 0 unless they are in a My Favorite\r\n else if ((!Librarian.extensions.hasFakeSlides(ext) || (data.presid > 0)) && !isNaN(count))\r\n data.slidecount = count;\r\n else\r\n data.slidecount = 0;\r\n }\r\n\r\n // If the parent has extra fields but the child doesn't, copy them over\r\n if (parentData.extrafields && !data.extrafields)\r\n data.extrafields = parentData.extrafields;\r\n }\r\n // If this is a child that doesn't have a slide count but does have a\r\n // PAGE count, set the slide count to the page count\r\n else if (isNaN(data.slidecount) && !isNaN(data.pagecount) && (data.pagecount > 0))\r\n data.slidecount = data.pagecount;\r\n else if (isNaN(data.slidecount) && !isNaN(count))\r\n data.slidecount = count;\r\n\r\n if (data.contenttype == Librarian.contentType.contentGroup) {\r\n // The \"slidenumber\" within a group refers to the slide number\r\n // from the source file. In order to avoid confusion, we use\r\n // an \"itemnumber\" property to define the slide number within this group.\r\n // Also, set the extension for the global here.\r\n if ((data.fileid > 0) && (data.itemnumber == null) && (typeof index == \"number\"))\r\n data.itemnumber = index + 1;\r\n if (!data.sourceext)\r\n data.sourceext = ext;\r\n data.filetypeextension = \"favg\";\r\n }\r\n else if (data.groupid > 0 && typeof data.eventcount == \"number\") {\r\n data.slidecount = data.eventcount;\r\n data.filetypeextension = \"evtg\";\r\n }\r\n // Set the extension for the virtual presentation\r\n else if (data.presid > 0) {\r\n if (!data.sourceext)\r\n data.sourceext = ext;\r\n data.filetypeextension = \"vpres\";\r\n if ((typeof data.prestype != \"number\") && (parentData != null))\r\n data.prestype = parentData.prestype;\r\n if (Librarian.Utils.isSlideShow(data)) {\r\n if (data.slidecount <= 0)\r\n data.slidecount = 1;\r\n if ((typeof data.itemnumber != \"number\") || (data.itemnumber < 0))\r\n data.itemnumber = 0;\r\n }\r\n }\r\n // Set the extension for events\r\n else if (data.eventid > 0) {\r\n data.filetypeextension = \"evt\";\r\n if (typeof totalIndex == \"number\")\r\n data.eventnumber = totalIndex + 1;\r\n if (parentData && parentData.eventgroupinfo && (parentData.eventgroupinfo.eventcount > 0))\r\n data.eventcount = parentData.eventgroupinfo.eventcount;\r\n else\r\n data.eventcount = count;\r\n }\r\n\r\n // If we aren't given a slidenumber, this is a file and we should set it to 0.\r\n if (data.slidenumber == undefined)\r\n data.slidenumber = 0;\r\n\r\n // If this is a fake slide from a file within a my favorite, set the slide number to its item number so the cart doesn't think this is a file\r\n if ((data.presid > 0) && (data.slidenumber == -1) && Librarian.extensions.hasFakeSlides(ext))\r\n data.slidenumber = data.itemnumber;\r\n },\r\n showProgressImage: function (referenceEl) {\r\n var progressEl = new Element(\"img\");\r\n progressEl.setStyles({\r\n paddingLeft: \"5px\",\r\n paddingTop: \"5px\",\r\n\r\n position: \"absolute\",\r\n zIndex: 5000\r\n });\r\n progressEl.id = \"progressImage\";\r\n\r\n progressEl.onload = function () {\r\n var parentEl = this.getParent();\r\n if (!parentEl)\r\n return;\r\n\r\n var parentSize = parentEl.getSize();\r\n // Set the top and left position of the image to be right in the middle of the parent\r\n this.style.top = (parentSize.y / 2) - (this.getHeight() / 2) + \"px\";\r\n this.style.left = (parentSize.x / 2) - (this.getWidth() / 2) + \"px\";\r\n }.bind(progressEl);\r\n\r\n if ((typeof referenceEl != \"undefined\") && (referenceEl != null)) {\r\n progressEl.id = referenceEl.id + '_' + progressEl.id;\r\n referenceEl.appendChild(progressEl);\r\n }\r\n else\r\n document.body.appendChild(progressEl);\r\n\r\n progressEl.src = Librarian.path.getImagesPath() + \"progress.gif\";\r\n\r\n return progressEl.id;\r\n },\r\n hideProgressImage: function (id) {\r\n if ((typeof id == \"undefined\") || (id == null))\r\n id = \"progressImage\";\r\n\r\n var progressEl = $(id);\r\n if (progressEl)\r\n progressEl.destroy();\r\n },\r\n showModalCover: function (contEl) {\r\n if (!contEl)\r\n return null;\r\n\r\n var coverEl = new Element(\"div\", {\r\n \"class\": \"modal-cover\",\r\n \"styles\": {\r\n \"height\": contEl.getScrollHeight() + \"px\"\r\n }\r\n }).injectInside(contEl);\r\n\r\n return coverEl;\r\n },\r\n isPackageNameValid: function (name, notify) {\r\n name = (name || '').trim();\r\n if (name.length == 0) {\r\n if (notify !== false)\r\n Librarian.Utils.error(Librarian.Lang.getArgString(\"create_namerequired\", [Librarian.Lang.getString(\"presentation\")]));\r\n return false;\r\n }\r\n\r\n if (!Librarian.Utils.checkString(name)) {\r\n if (notify !== false)\r\n Librarian.Utils.error(Librarian.Lang.getArgString(\"create_invalidname\", [Librarian.Lang.getString(\"presentation\"), Librarian.path.badChars]));\r\n return false;\r\n }\r\n\r\n if (Librarian.path.badNames.contains(name)) {\r\n if (notify !== false)\r\n Librarian.Utils.error(Librarian.Lang.getArgString(\"create_badname\", Librarian.Lang.getString(\"presentation\")));\r\n return false;\r\n }\r\n\r\n if (name.length > Librarian.path.maxFileNameLength) {\r\n if (notify !== false)\r\n Librarian.Utils.error(Librarian.Lang.getArgString(\"create_nametoolong\", [Librarian.Lang.getString(\"presentation\"), Librarian.path.maxFileNameLength]));\r\n return false;\r\n }\r\n\r\n return true;\r\n },\r\n getItemInformation: function (data, onSuccess, onFailure) {\r\n if (typeof onSuccess != \"function\")\r\n return;\r\n\r\n var url = null;\r\n\r\n if (data.presid > 0)\r\n url = Librarian.path.getMethodUrl(\"getvp\") + \"&pid=\" + data.presid + \"&out=dgrid\";\r\n else if (data.groupid > 0)\r\n url = Librarian.path.getMethodUrl(\"getgslides\") + \"&gid=\" + data.groupid + \"&out=dgrid&expand=\" + (Librarian.tileList.expandGroupItemsToSlides ? '1' : '0');\r\n else if (data.fileid > 0)\r\n url = Librarian.path.getMethodUrl(\"getslides\") + \"&fid=\" + data.fileid + \"&out=dgrid\";\r\n else if (data.catid != -1) {\r\n var type = data.type;\r\n\r\n if (type == Librarian.catType.myFavorite)\r\n url = Librarian.path.getMethodUrl(\"getvpci\") + \"&cid=\" + data.catid + \"&out=dgrid\";\r\n else if (type == Librarian.catType.globalFavorite)\r\n url = Librarian.path.getMethodUrl(\"getcgci\") + \"&cid=\" + data.catid + \"&out=dgrid\";\r\n else\r\n url = Librarian.path.getMethodUrl(\"getci\") + \"&cid=\" + data.catid + \"&out=dgrid\";\r\n }\r\n\r\n if (!url)\r\n return;\r\n\r\n var request = new Librarian.Request.JSON({\r\n url: url,\r\n onSuccess: onSuccess\r\n });\r\n if (typeof onFailure == \"function\")\r\n request.onFailure = onFailure;\r\n request.send();\r\n },\r\n logout: function () {\r\n var params = Librarian.features.sso.load ? \"?sso=false\" : \"\";\r\n\r\n Librarian.Utils.clearRequests();\r\n Librarian.Utils.clearSearchRequests();\r\n\r\n var session = new Librarian.Session();\r\n session.onLogoff = function () {\r\n // Remove session name from window\r\n var storedHash = window.name.parseQueryString();\r\n delete storedHash.sname;\r\n window.name = Object.toQueryString(storedHash);\r\n\r\n // Once logoff is complete, redirect\r\n Librarian.Utils.openPage(\"index.htm\" + params, false);\r\n };\r\n session.onFailure = function (error) {\r\n // If we got a 401, we're not authenicated anyway\r\n // so just redirect\r\n if (error && (error.status == 401))\r\n Librarian.Utils.openPage(\"index.htm\" + params, false);\r\n // Otherwise, alert the error text\r\n else {\r\n var index = this.response.text.indexOf('\\n'),\r\n message;\r\n if (index > 0)\r\n message = this.response.text.substr(0, index);\r\n else\r\n message = this.response.text;\r\n\r\n if (message.length > 0)\r\n Librarian.Utils.error(message, false);\r\n }\r\n };\r\n session.logoff();\r\n },\r\n openPage: function (page, keepHash, target) {\r\n if ((typeof keepHash == \"undefined\") || (keepHash == null))\r\n keepHash = true;\r\n if ((typeof target == \"undefined\") || (target == null))\r\n target = \"_self\";\r\n\r\n var hash = '';\r\n // If there is a hash on this url, keep it through the page load\r\n if (window.location.hash && keepHash)\r\n hash = window.location.hash;\r\n // If we're going to the login screen, keep the search path because it could contain \"sso=true\"\r\n if ((page == \"index.htm\") && window.location.search)\r\n page += window.location.search;\r\n\r\n // Add the build version to the end of the path to make sure it's unique and not cached, if it doesn't have it already\r\n if (!page.contains('?' + Librarian.buildVersion) && !page.contains('&' + Librarian.buildVersion))\r\n page += (page.contains('?') ? '&' : '?') + Librarian.buildVersion;\r\n\r\n window.open(page + Librarian.Utils.encodeHash(hash), target);\r\n },\r\n encodeHash: function (hash) {\r\n if (hash.length == 0)\r\n return hash;\r\n\r\n // Drop the # and split by all the &s\r\n var tags = hash.substring(1).split('&');\r\n\r\n // Go through each key-value pair\r\n for (var i = 0; i < tags.length; i++) {\r\n // Split by the = to separate the keys and values\r\n var values = tags[i].split('=');\r\n\r\n // Go through each key/value and encode it\r\n for (var j = 0; j < values.length; j++)\r\n values[j] = encodeURIComponent(decodeURIComponent(values[j]));\r\n\r\n // Rejoin this key-value pair\r\n tags[i] = values.join('=');\r\n }\r\n\r\n // Rejoin the entire hash with & and prepend the #\r\n return '#' + tags.join('&');\r\n },\r\n loadHomeContent: function (onNoHash) {\r\n // Hash navigation doesn't work at all on IE7, so don't even try\r\n if ((Browser.ie7 || !Librarian.Utils.onHashChange(this.getHash(), true)) && (typeof onNoHash == \"function\"))\r\n onNoHash();\r\n },\r\n onHashChange: function (hash, forced) {\r\n // Hash navigation doesn't work at all on IE7, so don't even try\r\n if (Browser.ie7 || !Librarian.hashNavigation)\r\n return false;\r\n\r\n if (Librarian.forcedHashChange === true) {\r\n Librarian.forcedHashChange = false;\r\n return true;\r\n }\r\n\r\n if (hash.length > 1) {\r\n var data = hash.parseQueryString();\r\n //Vue route, handled in router.js. skey handled differently\r\n if (data.vuePage || data.skey) {\r\n return true;\r\n }\r\n\r\n if (data.page != null) {\r\n if (typeof Library.loadPageFromHash == \"function\")\r\n return Library.loadPageFromHash(data);\r\n }\r\n\r\n // If this is a deeplink do a simple lookup\r\n // We can't do a server lookup because of the issue described in CLN-1311\r\n if (Librarian.isGuest) {\r\n if (data.fileid > 0) {\r\n var doLoad = function () {\r\n var root = treeView.root,\r\n openFile = function () {\r\n treeView.removeEvent(\"select\", openFile);\r\n Librarian.Utils.selectTreeNodeByPath(treeView, 'E' + Librarian.eventInfo.EventId + '/' + data.fileid);\r\n };\r\n if (root && !root.data)\r\n root = root.children[0];\r\n // There is code in place to automatically select the root node for a deep link, wait for that to happen and then open the preview window\r\n if (root && !root.state.open)\r\n treeView.addEvent(\"select\", openFile);\r\n else\r\n openFile();\r\n };\r\n\r\n // If the tree hasn't loaded yet, wait for it to do that\r\n if (!treeView.loaded)\r\n Librarian.Utils.runFunctionOnTreeEvent(treeView, \"loadChildren\", doLoad);\r\n else\r\n doLoad();\r\n\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n if (data.type == null)\r\n data.type = 0;\r\n\r\n // If loading the path fails, use this as a fallback\r\n var itemLoadFallback = function () {\r\n var list = tileList;\r\n if (typeof Library.getListByType == \"function\")\r\n list = Library.getListByType(this.type);\r\n\r\n // Try to get the information about the item from the server\r\n // This method looks the same as loading from the tree, but the\r\n // actual item isn't selected in the tree\r\n if (typeof Library.loadItemView == \"function\") {\r\n Librarian.Utils.getItemInformation(data, function (json) {\r\n if (!json || !json.data || (json.data.length == 0))\r\n return;\r\n\r\n var info = json.data[0];\r\n // This is a file\r\n if (info.fileinfo) {\r\n info = info.fileinfo;\r\n info.contenttype = Librarian.contentType.file;\r\n }\r\n // This is a content group\r\n if (info.groupinfo) {\r\n info = info.groupinfo;\r\n info.contenttype = Librarian.contentType.globalFavorite;\r\n }\r\n // This is a virtual presentation\r\n if (info.presid && info.items) {\r\n info = Object.subset(info, [\"name\", \"description\", \"presid\", \"slidecount\", \"createddate\", \"lastmoddate\"]);\r\n info.contenttype = Librarian.contentType.myFavorite;\r\n }\r\n\r\n var tree = Library.getTreeByType(this.type, this.tab, this.prestype);\r\n\r\n Librarian.Utils.onTreeSelect.bind(tree)({ data: info, name: info.name }, list);\r\n },\r\n function() {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cantfindintree\"));\r\n if (typeof Library.showHomePage == \"function\")\r\n Library.showHomePage();\r\n else if (typeof showHomePage == \"function\")\r\n showHomePage();\r\n }.bind(data));\r\n }\r\n // This is a last ditch effort to load the data\r\n // This is just a blank list with the given information, no page header\r\n else {\r\n Librarian.contentLoader.onComplete = list.loadComplete;\r\n Librarian.contentLoader.load(data, data.type);\r\n }\r\n };\r\n\r\n // If we can get the tree, try to load the file/category by path\r\n if (typeof Library.getTreeByType == \"function\") {\r\n Librarian.Utils.getPath(data, function (path) {\r\n if (path != null)\r\n Librarian.Utils.selectTreeNodeByPath(Library.getTreeByType(data.type, data.tab, data.prestype), path);\r\n // If the path wasn't found, fall back\r\n else\r\n itemLoadFallback();\r\n });\r\n }\r\n // Otherwise fall back\r\n else\r\n itemLoadFallback();\r\n\r\n if (data.preview == \"true\")\r\n Librarian.PreviewWindow.openPreviewWindow({\r\n fileid: data.fileid\r\n });\r\n\r\n return true;\r\n }\r\n\r\n // If this wasn't force loaded and there is a pageClick function,\r\n // load the home page beacuse we don't have a hash\r\n if (!Librarian.isGuest && (forced !== true)) {\r\n if (typeof Library.pageClick == \"function\") {\r\n Library.pageClick(\"home\");\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n },\r\n onTreeSelect: function (node, list, hashSuffix) {\r\n if (Librarian.hashNavigation)\r\n Librarian.Utils.changeTreeHash.bind(this)(node, hashSuffix);\r\n\r\n if (Librarian.myProcView != null)\r\n Librarian.myProcView.destroy();\r\n\r\n if (typeof Library.onTreeSelect == \"function\")\r\n Library.onTreeSelect.bind(this)(node, list);\r\n\r\n var mainPanelEl = $(\"mainPanel\");\r\n if (mainPanelEl)\r\n mainPanelEl.scrollTo(0, 0);\r\n else\r\n window.scrollTo(0, 0);\r\n },\r\n changeTreeHash: function (node, hashSuffix) {\r\n var hash = '';\r\n\r\n if (node.data.fileid > 0) {\r\n if ((this.options.catType == Librarian.catType.globalFavorite) ||\r\n (node.data.contenttype == Librarian.contentType.globalFavorite))\r\n hash = \"groupid=\" + node.data.fileid;\r\n else if (this.options.catType == Librarian.catType.myFavorite)\r\n hash = \"presid=\" + node.data.fileid;\r\n else if (this.options.catType == Librarian.catType.event)\r\n hash = \"groupid=\" + node.data.fileid;\r\n else\r\n hash = \"fileid=\" + node.data.fileid;\r\n }\r\n\r\n if (node.data.catid != null)\r\n hash += ((hash.length > 0) ? '&' : '') + \"catid=\" + node.data.catid;\r\n\r\n // Add the pres type as well\r\n if (node.data.prestype > 0)\r\n hash += \"&prestype=\" + node.data.prestype;\r\n\r\n hash += \"&type=\" + this.options.catType;\r\n\r\n // Save this setting so the Outlook plugin's portals can be special and use titles\r\n if (Librarian.isGuest && Librarian.tileList.useFileTitle)\r\n hash += \"&useTitle=true\";\r\n\r\n if (typeof hashSuffix == \"string\")\r\n hash += hashSuffix;\r\n\r\n Librarian.Utils.changeHash(hash);\r\n },\r\n\r\n changeHash: function (hash) {\r\n if (this.getHash() != hash) {\r\n Librarian.forcedHashChange = true;\r\n window.location.hash = hash;\r\n }\r\n\r\n // Make sure value is reset in case onHashChange is not triggered\r\n setTimeout(function() {\r\n Librarian.forcedHashChange = false;\r\n });\r\n },\r\n\r\n toggleListView: function (reload, saveUserSetting) {\r\n Librarian.listView.enabled = !Librarian.listView.enabled;\r\n if (saveUserSetting !== false)\r\n Librarian.Utils.setUserSetting(Librarian.ListView.enabledSetting, Librarian.listView.enabled);\r\n\r\n if (reload !== false) {\r\n if (!Librarian.search.isSearching) {\r\n if ((Library.curPage == \"home\") && (typeof Library.loadHome == \"function\"))\r\n Library.loadHome();\r\n else {\r\n if (Librarian.pageHeader && Librarian.pageHeader.options.headerType == Librarian.headerTypes.bookmark) {\r\n Librarian.Bookmarks.viewBookmarkedContents();\r\n } else {\r\n var trees = Librarian.treeViews;\r\n // Find the first tree with selection and run onTreeSelect on it\r\n for (var treeName in trees) {\r\n if (!trees.hasOwnProperty(treeName))\r\n continue;\r\n\r\n var tree = trees[treeName];\r\n if (tree != null) {\r\n var selected = tree.getSelected();\r\n if (selected) {\r\n Library.onTreeSelect.bind(tree)(selected, tileList, true);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n var search = Librarian.lastSearch,\r\n maxResults = Librarian.search.maxResults;\r\n\r\n if (Librarian.listView.enabled) {\r\n Librarian.Search.showSearchNavigation(false);\r\n maxResults = Librarian.ListView.prepSearchGrid(search, search.getOutputType());\r\n }\r\n else {\r\n search.options.loadComplete = tileList.searchLoadComplete;\r\n if (tileList && tileList.wrapper) {\r\n tileList.reset();\r\n tileList.wrapper.appendChild(document.createTextNode(Librarian.Lang.getString(\"searching\")));\r\n }\r\n }\r\n\r\n search.addResults(null, maxResults);\r\n Librarian.lastSearch = search;\r\n search.search();\r\n }\r\n }\r\n\r\n var itemEl = $(\"toggleList\");\r\n if (itemEl) {\r\n if (Librarian.listView.enabled)\r\n itemEl.set(\"text\", \"Thumbnail View\");\r\n else\r\n itemEl.set(\"text\", \"List View\");\r\n }\r\n\r\n itemEl = $(\"expandCollapseContainer\");\r\n if (itemEl) {\r\n if (Librarian.listView.enabled)\r\n itemEl.show(\"inline\");\r\n else\r\n itemEl.hide();\r\n }\r\n\r\n itemEl = null;\r\n },\r\n toggleTagCloudView: function (enable, data) {\r\n if (!Librarian.features.tagcloud.load) {\r\n return;\r\n }\r\n\r\n if (enable) {\r\n //Hide related content\r\n var relatedContentEl = $(\"relatedContent\");\r\n if (relatedContentEl) {\r\n relatedContentEl.hide();\r\n }\r\n\r\n if (tileList) {\r\n // Reset the TileList\r\n tileList.reset();\r\n }\r\n\r\n if (Librarian.tagCloudView) {\r\n Librarian.tagCloudView.reload(data);\r\n } else {\r\n Librarian.tagCloudView = new Librarian.TagCloudView({\r\n container: $(\"tileListWrapper\"),\r\n data: data\r\n });\r\n }\r\n } else {\r\n if (Librarian.tagCloudView) {\r\n if (Librarian.tagCloudView.isVisible()) {\r\n Librarian.tagCloudView.clean();\r\n\r\n if ((Library.curPage == \"home\") && (typeof Library.loadHome == \"function\"))\r\n Library.loadHome();\r\n else {\r\n var trees = Librarian.treeViews;\r\n // Find the first tree with selection and run onTreeSelect on it\r\n for (var treeName in trees) {\r\n if (!trees.hasOwnProperty(treeName))\r\n continue;\r\n\r\n var tree = trees[treeName];\r\n if (tree != null) {\r\n var selected = tree.getSelected();\r\n if (selected) {\r\n Library.onTreeSelect.bind(tree)(selected, tileList, true);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n },\r\n getStandardContent: function (content) {\r\n content = Object.toLowerKeys(content);\r\n\r\n // Standardize contentname\r\n content.contentname = content.name || content.contentname;\r\n\r\n // Standardize content type\r\n if (!content.contenttype) {\r\n if (content.slideid > 0)\r\n content.contenttype = Librarian.contentType.slide;\r\n else if (content.groupid > 0) {\r\n if (content.ext == \"evtg\")\r\n content.contenttype = Librarian.contentType.eventGroup;\r\n else\r\n content.contenttype = Librarian.contentType.globalFavorite;\r\n }\r\n else if (content.presid > 0 && (content.ext == \"vpres\" || content.sourceext == null))\r\n content.contenttype = Librarian.contentType.myFavorite;\r\n else if (content.fileid > 0 || content.fileId > 0)\r\n content.contenttype = Librarian.contentType.file;\r\n else if (content.catid >= 0) {\r\n content.contenttype = Librarian.contentType.category;\r\n\r\n if ((content.cattype == Librarian.catType.myFavorite) || content.presentations)\r\n content.contenttype = Librarian.contentType.myFavoriteCategory;\r\n }\r\n }\r\n\r\n // Standardize content id\r\n if (content.contenttype == Librarian.contentType.globalFavorite)\r\n content.contentid = content.groupid || content.fileid || content.contentid;\r\n else if (content.contenttype == Librarian.contentType.myFavorite)\r\n content.contentid = content.presid || content.fileid || content.contentid;\r\n else if (content.contenttype == Librarian.contentType.slide) {\r\n content.contentid = content.slideid || content.contentid;\r\n\r\n if (content.slidenumber && content.filename)\r\n content.contentname = Librarian.Utils.getItemTypeString(content) + \" \" + content.slidenumber + \" in \" + content.filename;\r\n }\r\n else if (content.contenttype == Librarian.contentType.file) {\r\n content.contentid = content.fileid || content.fileId || content.contentid;\r\n content.contentname = content.filename || content.contentname;\r\n }\r\n else if ((content.contenttype == Librarian.contentType.category) || (content.contenttype == Librarian.contentType.myFavoriteCategory))\r\n content.contentid = (content.catid >= 0) ? content.catid : content.contentid;\r\n else if (content.contenttype == Librarian.contentType.eventGroup)\r\n content.contentid = content.groupid || content.contentid;\r\n\r\n return content;\r\n },\r\n getFromContent: function (content) {\r\n if (!content || !content.contentid || (typeof content.contenttype != \"number\") || !content.contentname)\r\n return content;\r\n\r\n var item = {\r\n contenttype: content.contenttype\r\n };\r\n\r\n if (content.contenttype == Librarian.contentType.slide) {\r\n item.slideid = content.contentid;\r\n item.filename = content.contentname;\r\n item.title = content.title;\r\n }\r\n else if (content.contenttype == Librarian.contentType.file) {\r\n item.fileid = content.contentid;\r\n item.filename = content.contentname;\r\n item.title = content.title;\r\n }\r\n else {\r\n item.name = content.contentname;\r\n if (content.contenttype == Librarian.contentType.globalFavorite)\r\n item.groupid = content.contentid;\r\n else if (content.contenttype == Librarian.contentType.myFavorite)\r\n item.presid = content.contentid;\r\n else if ((content.contenttype == Librarian.contentType.category) || (content.contenttype == Librarian.contentType.myFavoriteCategory))\r\n item.catid = content.contentid;\r\n }\r\n\r\n return item;\r\n },\r\n getContentTypeName: function (content) {\r\n if ((typeof content == \"undefined\") || (content == null))\r\n return \"\";\r\n\r\n var itemType = '';\r\n switch (content.contenttype) {\r\n case Librarian.contentType.file:\r\n itemType = \"file\";\r\n break;\r\n case Librarian.contentType.globalFavorite:\r\n itemType = \"favorite_global\";\r\n break;\r\n case Librarian.contentType.myFavorite:\r\n itemType = \"favorite_generic\";\r\n break;\r\n case Librarian.contentType.category:\r\n case Librarian.contentType.myFavoriteCategory:\r\n itemType = \"category\";\r\n break;\r\n case Librarian.contentType.slide:\r\n itemType = Librarian.Utils.getItemType(content);\r\n break;\r\n }\r\n\r\n return Librarian.Lang.getString(itemType);\r\n },\r\n getContentTypeIcon: function (content) {\r\n if ((typeof content === \"undefined\") || (content === null)) {\r\n return '';\r\n }\r\n\r\n content = Object.toLowerKeys(content);\r\n\r\n var contentType = parseInt(content.contenttype, 10);\r\n if (isNaN(contentType)) {\r\n return '';\r\n }\r\n\r\n var ext = Librarian.Utils.getExtensionFromData(content, true),\r\n icon = '',\r\n category = false;\r\n switch (contentType) {\r\n case Librarian.contentType.file:\r\n icon = ext;\r\n break;\r\n case Librarian.contentType.globalFavorite:\r\n icon = \"favg\";\r\n break;\r\n case Librarian.contentType.myFavorite:\r\n icon = \"vpres\";\r\n break;\r\n case Librarian.contentType.category:\r\n case Librarian.contentType.myFavoriteCategory:\r\n icon = \"category\";\r\n category = true;\r\n break;\r\n case Librarian.contentType.slide:\r\n if (ext.startsWith(\"ppt\") || ext.startsWith(\"pps\") || ext.startsWith(\"pot\")) {\r\n icon = \"ppt_slide\";\r\n } else if (ext == \"pdf\") {\r\n icon = \"pdf_page\";\r\n } else {\r\n icon = ext;\r\n }\r\n break;\r\n }\r\n\r\n if (Librarian.extensions.isCategorizedFileTypeIcons()) {\r\n return Librarian.Utils.getFileTypeIcon(ext, null, category);\r\n }\r\n\r\n return Librarian.path.getFileTypeIconsPath(\"v1\") + icon + \".gif\";\r\n },\r\n getCategoryTypeFromContentType: function (contentType) {\r\n switch (contentType) {\r\n case Librarian.contentType.file:\r\n return Librarian.catType.file;\r\n case Librarian.contentType.globalFavorite:\r\n return Librarian.catType.globalFavorite;\r\n case Librarian.contentType.sharedFavoriteCategory:\r\n case Librarian.contentType.sharedFavorite:\r\n case Librarian.contentType.myFavorite:\r\n case Librarian.contentType.myFavoriteCategory:\r\n return Librarian.catType.myFavorite;\r\n case Librarian.contentType.eventGroup:\r\n return Librarian.catType.event;\r\n case Librarian.contentType.workItem:\r\n return Librarian.catType.workflow;\r\n }\r\n return Librarian.catType.undefined;\r\n },\r\n getContentTypeFromCategoryType: function (catType, slide) {\r\n if (slide === true) {\r\n if (catType == Librarian.catType.event)\r\n return Librarian.contentType.event;\r\n if (catType == Librarian.catType.articles)\r\n return Librarian.contentType.articleSection;\r\n return Librarian.contentType.slide;\r\n }\r\n\r\n switch (catType) {\r\n case Librarian.catType.file:\r\n case Librarian.catType.uploads:\r\n case Librarian.catType.download:\r\n return Librarian.contentType.file;\r\n case Librarian.catType.globalFavorite:\r\n return Librarian.contentType.globalFavorite;\r\n case Librarian.catType.event:\r\n return Librarian.contentType.eventGroup;\r\n case Librarian.catType.myFavorite:\r\n return Librarian.contentType.myFavorite; // TODO: Support other favorite types, somehow\r\n case Librarian.catType.articles:\r\n return Librarian.contentType.article;\r\n }\r\n return Librarian.contentType.undefined;\r\n },\r\n canEditFavoriteAccess: function (data) {\r\n if (!Librarian.features.sharedfavorite.load)\r\n return false;\r\n\r\n return Librarian.Utils.isOwner(data) && Librarian.Utils.isShared(data);\r\n },\r\n isOwner: function (data) {\r\n if (!data)\r\n return false;\r\n var catId = (data.catid || data.catId || -1).toInt(),\r\n // Check prestype to make sure this is a Favorite category\r\n isCat = ((typeof data.prestype == \"number\") && (catId >= 0)),\r\n presid = (data.presid || data.presId || (isCat ? catId : -1) || -1).toInt();\r\n if (presid < 0)\r\n return false;\r\n\r\n return (data.isowner === true) || (data.isOwner === true);\r\n },\r\n canWrite: function (data) {\r\n if (!data)\r\n return false;\r\n var presid = (data.presid || data.presId || -1).toInt();\r\n if (presid < 0)\r\n return false;\r\n\r\n return (data.isowner === true) || (data.isOwner === true) || (data.canwrite === true) || (data.canWrite === true);\r\n },\r\n isSlideShow: function (data) {\r\n if (!data)\r\n return false;\r\n var presid = (data.presid || data.presId || -1).toInt();\r\n if (presid < 0)\r\n return false;\r\n\r\n if (!data.isslideshow && !data.isSlideshow)\r\n return Librarian.Utils.isFavoriteType([Librarian.virtPresType.slideshow, Librarian.virtPresType.sharedSlideshow]);\r\n return true;\r\n },\r\n isFavorite: function (data) {\r\n if (!data)\r\n return false;\r\n var presid = (data.presid || data.presId || -1).toInt();\r\n if (presid < 0)\r\n return false;\r\n\r\n if (!data.isfavorite && !data.isFavorite)\r\n return Librarian.Utils.isFavoriteType([Librarian.virtPresType.myFavorite, Librarian.virtPresType.sharedFavorite]);\r\n return true;\r\n },\r\n isShared: function (data) {\r\n if (!data)\r\n return false;\r\n var presid = (data.presid || data.presId || -1).toInt();\r\n if (presid < 0)\r\n return false;\r\n\r\n if (!data.isshared && !data.isShared)\r\n return Librarian.Utils.isFavoriteType([Librarian.virtPresType.sharedFavorite, Librarian.virtPresType.sharedSlideshow]);\r\n return true;\r\n },\r\n isMyFavorite: function (data) {\r\n return Librarian.Utils.isFavoriteType(data, Librarian.virtPresType.myFavorite);\r\n },\r\n isMySlideShow: function (data) {\r\n return Librarian.Utils.isFavoriteType(data, Librarian.virtPresType.slideshow);\r\n },\r\n isSharedFavorite: function (data) {\r\n return Librarian.Utils.isFavoriteType(data, Librarian.virtPresType.sharedFavorite);\r\n },\r\n isSharedSlideShow: function (data) {\r\n return Librarian.Utils.isFavoriteType(data, Librarian.virtPresType.sharedSlideshow);\r\n },\r\n isFavoriteType: function (data, types) {\r\n if (!data)\r\n return false;\r\n var presid = (data.presid || data.presId || -1).toInt();\r\n if (presid < 0)\r\n return false;\r\n\r\n types = Array.from(types);\r\n return types.contains(data.prestype) || types.contains(data.presType);\r\n },\r\n onFailure: function(error) {\r\n if (!error)\r\n return;\r\n\r\n if (typeof error == \"object\")\r\n error = error.responseText || \"\";\r\n\r\n var index = error.indexOf('\\n');\r\n if (index > 0)\r\n error = error.substr(0, index);\r\n\r\n if (error)\r\n Librarian.Utils.error(error, false);\r\n },\r\n getMooSelectContact: function (contact) {\r\n // Dynamics crm\r\n if (typeof contact.contactid == \"string\")\r\n delete contact.contactid;\r\n\r\n var text = contact.text || contact.displayname || contact.fullname || contact.name || contact.email;\r\n var value = contact.value;\r\n\r\n if (!value) {\r\n if (contact.contactid && contact.contacttype)\r\n value = contact.contactid + '-' + contact.contacttype;\r\n else\r\n value = contact.id || contact.email;\r\n }\r\n\r\n contact.text = text;\r\n contact.value = value;\r\n\r\n return contact;\r\n },\r\n parseCsv: function (text, delimeter) {\r\n var csvJson = text.match(/[^\\r\\n]+/g),\r\n objAttributeNames = csvJson[0].split(\"/[\" + delimeter + \"]+/g\");\r\n\r\n csvJson.slice(1);\r\n\r\n for (var i = csvJson.length; i--;) {\r\n var objValues = csvJson[i].split(\"/[\" + delimeter + \"]+/g\");\r\n for (var j = objAttributeNames.length; j--;) {\r\n csvJson[i] = {};\r\n csvJson[i][objAttributeNames[j]] = objValues[j];\r\n }\r\n }\r\n\r\n return csvJson;\r\n },\r\n isDataEqual: function (firstData, secondData) {\r\n if (typeof Library.isDataEquals == \"function\") {\r\n return Library.isDataEquals(firstData, secondData);\r\n }\r\n return firstData.contentid == secondData.contentid && firstData.contenttype == secondData.contenttype;\r\n },\r\n isUserMemberOfGroup: function (groupNames) {\r\n // Don't check anything if we don't have the groups list\r\n if (typeOf(Librarian.userGroups) != \"array\")\r\n return false;\r\n if ((typeof groupNames == \"undefined\") || (groupNames == null))\r\n return false;\r\n\r\n groupNames = Array.from(groupNames).invoke('toLowerCase');\r\n\r\n return Librarian.userGroups.filter(function (item) {\r\n return groupNames.contains(item.Name.toLowerCase());\r\n }).length > 0;\r\n },\r\n // Check if a user is a member of a group where the passed in groups are partial group names\r\n // Someone in the 'Everyone' group would return true for groupName = ['everyone', 'every', 'e']\r\n isUserMemberOfGroupLike: function (groupNames) {\r\n // Don't check anything if we don't have the groups list\r\n if (typeOf(Librarian.userGroups) != \"array\")\r\n return false;\r\n if ((typeof groupNames == \"undefined\") || (groupNames == null))\r\n return false;\r\n\r\n groupNames = Array.from(groupNames).invoke('toLowerCase');\r\n\r\n return Librarian.userGroups.filter(function (item) {\r\n return groupNames.filter(function (group) {\r\n return (item.Name.toLowerCase().indexOf(group) >= 0);\r\n }).length > 0;\r\n }).length > 0;\r\n },\r\n requestStatuses: {},\r\n requestStatusRequest: null,\r\n requestStatusTimer: null,\r\n trackRequestStatus: function (requestId, onSuccess, onFailure) {\r\n if (!Librarian.Utils.requestStatuses[requestId])\r\n Librarian.Utils.requestStatuses[requestId] = { onSuccess: onSuccess, onFailure: onFailure };\r\n\r\n if (!Librarian.Utils.requestStatusTimer)\r\n Librarian.Utils.requestStatusTimer = setTimeout(Librarian.Utils.checkRequestStatuses, 5000);\r\n },\r\n checkRequestStatuses: function () {\r\n // Stop the timer, if it exists, just in case\r\n if (Librarian.Utils.requestStatusTimer)\r\n clearTimeout(Librarian.Utils.requestStatusTimer);\r\n\r\n // Get all of the request ids whose items are not null\r\n var requestIds = Object.keys(Object.filter(Librarian.Utils.requestStatuses, function (value) { return value != null; }));\r\n // If there are no more requests, null out the timer and stop\r\n if (requestIds.length == 0) {\r\n Librarian.Utils.requestStatusTimer = null;\r\n return;\r\n }\r\n // Otherwise, set up another timer loop\r\n else\r\n Librarian.Utils.requestStatusTimer = setTimeout(Librarian.Utils.checkRequestStatuses, 5000);\r\n\r\n // If the request hasn't finished yet, don't send another\r\n if (Librarian.Utils.requestStatusRequest != null)\r\n return;\r\n\r\n // Send a check request for all of the request ids in the list\r\n Librarian.Utils.requestStatusRequest = new Librarian.Request.JSON({\r\n url: Librarian.path.getMethodUrl(\"crst\") + \"&out=ujson&rid=\" + encodeURIComponent(requestIds.join(',')),\r\n onSuccess: Librarian.Utils.onRequestCheckComplete\r\n });\r\n Librarian.Utils.requestStatusRequest.send();\r\n },\r\n onRequestCheckComplete: function (json) {\r\n for (var i = 0; i < json.length; i++) {\r\n var data = json[i],\r\n request = Librarian.Utils.requestStatuses[data.RequestId];\r\n\r\n if (data.Failed) {\r\n if (request && (typeof request.onFailure == \"function\"))\r\n request.onFailure(data);\r\n\r\n Librarian.Utils.requestStatuses[data.RequestId] = null;\r\n }\r\n else if (data.Complete) {\r\n if (request && (typeof request.onSuccess == \"function\"))\r\n request.onSuccess(data);\r\n\r\n Librarian.Utils.requestStatuses[data.RequestId] = null;\r\n }\r\n }\r\n\r\n Librarian.Utils.requestStatusRequest = null;\r\n },\r\n openRecEngine: function (page, pageData) {\r\n Librarian.recWindow = new Librarian.CustomWizardWindow({\r\n xmlURL: Librarian.path.getLibraryPath() + \"wizard/wizard.xml\",\r\n navMenuStyle: \"rec-eng-menu\",\r\n navMenuTitleStyle: \"menu-subhead\",\r\n page: page,\r\n pageData: pageData\r\n });\r\n Librarian.recWindow.show();\r\n },\r\n keysToLowerCase: function(obj) {\r\n var keys = Object.keys(obj);\r\n var n = keys.length;\r\n while (n--) {\r\n var key = keys[n]; // \"cache\" it, for less lookups to the array\r\n if (key !== key.toLowerCase()) { // might already be in its lower case version\r\n obj[key.toLowerCase()] = obj[key]; // swap the value to a new lower case key\r\n delete obj[key]; // delete the old key\r\n }\r\n }\r\n return (obj);\r\n },\r\n log: function (text) {\r\n if (window.console)\r\n console.log(text);\r\n },\r\n logInfo: function (info, text) {\r\n if (window.console)\r\n console.info(info, text);\r\n },\r\n logPreviewActivity: function (data, id, params) {\r\n var contentId = -1, contentType = Librarian.contentType.undefined, parentId = -1, parentType = Librarian.contentType.undefined;\r\n if (data.slideid > 0) {\r\n contentId = data.slideid;\r\n contentType = Librarian.contentType.slide;\r\n\r\n if (data.presid > 0) {\r\n parentId = data.presid;\r\n parentType = Librarian.contentType.myFavorite;\r\n }\r\n else if (data.groupid > 0) {\r\n parentId = data.groupid;\r\n parentType = Librarian.contentType.globalFavorite;\r\n }\r\n else if (data.fileid > 0) {\r\n parentId = data.fileid;\r\n parentType = Librarian.contentType.file;\r\n }\r\n }\r\n else if (data.presid > 0) {\r\n contentId = data.presid;\r\n contentType = Librarian.contentType.myFavorite;\r\n }\r\n else if (data.groupid > 0) {\r\n contentId = data.groupid;\r\n contentType = Librarian.contentType.globalFavorite;\r\n }\r\n else if (data.fileid > 0) {\r\n contentId = data.fileid;\r\n contentType = Librarian.contentType.file;\r\n }\r\n else if ((data.contentid > 0) || (data.contentId > 0)) {\r\n contentId = data.contentid || data.contentId;\r\n contentType = data.contenttype || data.contentType;\r\n }\r\n\r\n if ((contentId == -1) || (contentType == Librarian.contentType.undefined))\r\n return;\r\n\r\n var url = Librarian.path.getLogUrl(\"logprv\") + \"&cntid=\" + contentId + \"&cnttype=\" + contentType + \"&parid=\" + parentId + \"&partype=\" + parentType + \"&id=\" + id;\r\n\r\n if (params)\r\n url += \"&\" + Object.toQueryString(params);\r\n\r\n new Librarian.Request({\r\n url: url\r\n }).send();\r\n },\r\n logActivityDuration: function (id, sync) {\r\n // Send this request to the server to note that we are done looking at this slide\r\n new Librarian.Request({\r\n url: Librarian.path.getLogUrl(\"logactd\") + \"&id=\" + id,\r\n async: sync !== true\r\n }).send();\r\n },\r\n getContactFeaturePermissions: function (contact) {\r\n Librarian.Utils.getFeaturePermissions(\r\n function (json) {\r\n contact.features = json;\r\n },\r\n \"getftrpermact\",\r\n \"&coid=\" + contact.contactid + \"&cotype=\" + contact.contacttype\r\n );\r\n },\r\n getUserFeaturePermissions: function () {\r\n Librarian.Utils.getFeaturePermissions(\r\n function (json) {\r\n Librarian.userInfo.features = json;\r\n },\r\n \"getftrpermu\"\r\n );\r\n },\r\n getFeaturePermissions: function (onSuccess, method, options) {\r\n if ((typeof onSuccess != \"function\") || !method)\r\n return;\r\n\r\n new Librarian.Request.JSON({\r\n url: Librarian.path.getAdminUrl(method) + (options || '') + \"&out=cjson\",\r\n onSuccess: onSuccess\r\n }).send();\r\n },\r\n // Source: http://phpjs.org/functions/strip_tags:535\r\n stripHTML: function (text, allowedTags) {\r\n // Make sure the allowed arg is a string containing only tags in lowercase ()\r\n allowedTags = (((allowedTags || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('');\r\n var tags = /<\\/?([a-z][a-z0-9]*)\\b[^>]*>/gi,\r\n commentsAndPhpTags = /|<\\?(?:php)?[\\s\\S]*?\\?>/gi;\r\n return text.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {\r\n return allowedTags.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';\r\n });\r\n },\r\n getTinyMCEStyles: function (type) {\r\n if (!type)\r\n type = \"editor\";\r\n\r\n var css = [Librarian.path.getLayoutsPath() + \"tinymce/\" + type + \".css\"];\r\n if (Librarian.editor.customCSSPath.length > 0)\r\n css.push(Librarian.editor.customCSSPath);\r\n if (Librarian.features.metroui.load)\r\n css.push(Librarian.path.getLayoutsPath() + \"tinymce/metro.css\");\r\n\r\n return css.join(',');\r\n },\r\n getTinyMCEDefaults: function () {\r\n return {\r\n plugins: \"lists advlist code link hr\",\r\n toolbar: \"bold italic underline | alignleft aligncenter alignright | fontsize | link forecolor removeformat\",\r\n resize: false,\r\n menubar: false,\r\n statusbar: false,\r\n forced_root_block: false,\r\n convert_urls: false,\r\n browser_spellcheck: true,\r\n force_hex_style_colors: true,\r\n // Override element rules; don't pad td with nbsp\r\n extended_valid_elements: \"td[*]\",\r\n custom_elements: \"style\",\r\n allow_conditional_comments: true,\r\n formats: {\r\n // Override img to use align instead of float\r\n alignleft: [\r\n { selector: 'img', collapsed: false, attributes: { 'align': 'left' } }\r\n ],\r\n alignright: [\r\n { selector: 'img', collapsed: false, attributes: { 'align': 'right' } }\r\n ],\r\n // Use text-align instead of margin: auto\r\n aligncenter: { block: 'p', styles: { 'text-align': 'center' } }\r\n },\r\n content_css: Librarian.Utils.getTinyMCEStyles(),\r\n toolbar_mode: 'wrap',\r\n visual_table_class: \"none\" // Hack since it won't allow us to pass an empty value\r\n };\r\n },\r\n getTinyMCEOptions: function (instanceOptions) {\r\n var defaults = Librarian.Utils.getTinyMCEDefaults(),\r\n libraryOptions = Librarian.editor.options;\r\n\r\n return Object.merge({}, defaults, libraryOptions, instanceOptions);\r\n },\r\n // Adds to the available buttons, but still has to be included in the toolbar options\r\n addTinyMCEButton: function (editor, button) {\r\n var buttons = {\r\n \"insertgreeting\": {\r\n tooltip: Librarian.Lang.getString(\"greeting_tooltip\"),\r\n text: Librarian.Lang.getString(\"greeting_text\"),\r\n onAction: function () {\r\n editor.selection.setCursorLocation(editor.getBody(), 0);\r\n editor.insertContent('[Email Greeting],

');\r\n }\r\n },\r\n \"insertsignature\": {\r\n tooltip: Librarian.Lang.getString(\"signature_tooltip\"),\r\n text: Librarian.Lang.getString(\"signature_text\"),\r\n onAction: function() {\r\n editor.insertContent('[Email Signature]');\r\n }\r\n },\r\n \"insertportal\": {\r\n tooltip: Librarian.Lang.getString(\"portal_link_tooltip\"),\r\n text: Librarian.Lang.getString(\"portal_link_text\"),\r\n onAction: function () {\r\n editor.insertContent('[Portal Link]');\r\n }\r\n },\r\n \"insertcontentlink\": {\r\n tooltip: Librarian.Lang.getString(\"content_link_tooltip\"),\r\n text: Librarian.Lang.getString(\"content_link_text\"),\r\n onAction: function () {\r\n editor.insertContent('[Content Link]');\r\n }\r\n },\r\n \"insertdownloadlink\": {\r\n tooltip: Librarian.Lang.getString(\"download_link_tooltip\"),\r\n text: Librarian.Lang.getString(\"download_link_text\"),\r\n onAction: function () {\r\n editor.insertContent('[Download Link]');\r\n }\r\n },\r\n \"insertimage\": {\r\n tooltip: Librarian.Lang.getString(\"insert_image_tooltip\"),\r\n icon: \"image\",\r\n onAction: function () {\r\n // Fix for IE11 inserting at beginning after losing focus\r\n // https://stackoverflow.com/a/22132612\r\n var position = editor.selection.getBookmark();\r\n\r\n var imageWin = new Librarian.ImageSelectWindow({\r\n params: {\r\n subtype: Librarian.supportImageSubType.event,\r\n tmpl: false,\r\n all: true\r\n },\r\n onSuccess: function (image) {\r\n var url = Librarian.path.getAbsolutePath(Librarian.path.getDownloadUrl(\"dsf\")) + \"&fh=\" + image.hash;\r\n\r\n editor.selection.moveToBookmark(position);\r\n\r\n if (Librarian.event.maxImgWidth != null) {\r\n var img = new Image();\r\n img.src = url;\r\n img.addEventListener(\"load\", function () {\r\n var width = this.naturalWidth;\r\n if (width > Librarian.event.maxImgWidth)\r\n width = Librarian.event.maxImgWidth;\r\n\r\n editor.insertContent(\"\");\r\n });\r\n }\r\n else {\r\n editor.insertContent(\"\");\r\n }\r\n }\r\n });\r\n }\r\n },\r\n \"insertdisclosure\": {\r\n tooltip: Librarian.Lang.getString(\"insert_disc_tooltip\"),\r\n text: Librarian.Lang.getString(\"insert_disc_text\"),\r\n onAction: function () {\r\n // Fix for IE11 inserting at beginning after losing focus\r\n // https://stackoverflow.com/a/22132612\r\n var position = editor.selection.getBookmark();\r\n\r\n var discWin = new Librarian.DisclosureWindow({\r\n type: Librarian.disclosureType.email\r\n });\r\n discWin.addEvent(\"complete\", function (disclosures) {\r\n disclosures = Array.from(disclosures);\r\n\r\n disclosures.forEach(function (disclosure) {\r\n var placeholder = \"{!disclosure:id=\" + disclosure.disclosureid + \"}\",\r\n html = \"

\" + placeholder + \"

\";\r\n\r\n editor.selection.moveToBookmark(position);\r\n editor.insertContent(html);\r\n });\r\n });\r\n }\r\n }\r\n }\r\n\r\n var options = buttons[button];\r\n if (options)\r\n editor.ui.registry.addButton(button, options);\r\n },\r\n getLibrarySetting: function (name, onSuccess, onFailure) {\r\n if (typeof onSuccess != \"function\")\r\n return;\r\n if (!name)\r\n return;\r\n if (typeof name == \"string\")\r\n name = [name];\r\n var count = name.length,\r\n settings = {};\r\n for (var i = name.length; i--;) {\r\n (function (name) {\r\n var request = new Librarian.Request.JSON({\r\n url: Librarian.path.getMethodUrl(\"getsettval\") + \"&name=\" + name + \"&out=ujson\",\r\n onSuccess: function (value) {\r\n var parsedValue;\r\n try {\r\n parsedValue = parseInt(value);\r\n if (isNaN(parsedValue)) {\r\n parsedValue = value;\r\n\r\n if (parsedValue.toLowerCase() == \"true\")\r\n parsedValue = true;\r\n else if (parsedValue.toLowerCase() == \"false\")\r\n parsedValue = false;\r\n }\r\n }\r\n catch (e) {\r\n parsedValue = value;\r\n }\r\n settings[name] = parsedValue;\r\n if (!--count)\r\n onSuccess(settings);\r\n },\r\n onFailure: function(error) {\r\n if (!--count) {\r\n if (Object.keys(settings).length != 0)\r\n onSuccess(settings);\r\n }\r\n\r\n Librarian.Utils.onFailure(error);\r\n if (typeof onFailure == \"function\")\r\n onFailure(name);\r\n }\r\n });\r\n request.send();\r\n })(name[i]);\r\n }\r\n },\r\n getUserGroupInfo: function (groupName, includeMembers, onSuccess, onFailure) {\r\n var request = new Request.JSON({\r\n method: \"get\",\r\n url: Librarian.path.getMethodUrl(\"getugi\") + \"&out=cjson&members=\" + (!!includeMembers ? '1' : '0') + \"&name=\" + encodeURIComponent(groupName),\r\n onSuccess: onSuccess,\r\n onFailure: onFailure || Librarian.Utils.onFailure\r\n });\r\n request.send();\r\n\r\n return request;\r\n },\r\n setupSDDMMenu: function(options, container) {\r\n var menuEl = new Element(\"li\", options.menuProperties);\r\n\r\n var linkEl = new Element(\"a\", options.linkProperties).injectInside(menuEl);\r\n\r\n if (options.linkIconClass)\r\n var iconEl = new Element(\"span\", { \"class\": options.linkIconClass }).injectInside(linkEl);\r\n\r\n if (options.linkText)\r\n var textEl = new Element(\"span\", { \"text\": options.linkText }).injectInside(linkEl);\r\n\r\n var dropdownEl = new Element(\"div\", options.dropdownProperties).injectInside(menuEl);\r\n\r\n Librarian.Utils.populateSDDMDropdown(dropdownEl, options.dropdownItems);\r\n Librarian.Utils.bindSDDMMenu(linkEl, dropdownEl);\r\n\r\n var containerEl = $(container);\r\n if (containerEl)\r\n menuEl.injectInside(containerEl);\r\n\r\n return menuEl;\r\n },\r\n populateSDDMDropdown: function(dropdownEl, dropdownItems) {\r\n dropdownItems.forEach(function(item) {\r\n var itemEl = new Element(\"a\", item.properties).injectInside(dropdownEl);\r\n\r\n if (typeof item.onClick == \"function\")\r\n itemEl.addOnClick(item.onClick);\r\n });\r\n },\r\n bindSDDMMenus: function (items) {\r\n if (!items)\r\n return;\r\n for (var i = items.length; i--;) {\r\n var parentEl = $(items[i].parent),\r\n menuEl = $(items[i].menu),\r\n onClick = items[i].onClick;\r\n Librarian.Utils.bindSDDMMenu(parentEl, menuEl, onClick);\r\n }\r\n },\r\n bindSDDMMenu: function (parentEl, menuEl, onClick) {\r\n if (parentEl && menuEl) {\r\n var clickFn = Librarian.isSurface() ? mopen.partial(menuEl, parentEl) : onClick;\r\n\r\n parentEl.addEvents({\r\n click: clickFn,\r\n mouseover: mopen.partial(menuEl, parentEl),\r\n mouseout: mclosetime,\r\n blur: mclosetime,\r\n });\r\n\r\n menuEl.addEvents({\r\n mouseover: mcancelclosetime,\r\n mouseout: mclosetime,\r\n blur: mclosetime,\r\n click: mclose\r\n });\r\n }\r\n },\r\n getFlaggingLocation: function (location) {\r\n switch (location) {\r\n case 0:\r\n return \"top-left\";\r\n case 1:\r\n return \"top-right\";\r\n case 2:\r\n return \"bottom-right\";\r\n case 3:\r\n default:\r\n return \"bottom-left\";\r\n }\r\n },\r\n getFlaggingClasses: function(data) {\r\n var mapping = Librarian.flagging.mapping;\r\n\r\n if (!Librarian.flagging.enabled || !data || !mapping)\r\n return [];\r\n\r\n // Backwards compatibility with name/value settings\r\n if (typeOf(mapping) != \"array\") {\r\n mapping = Object.toArray(mapping, function(value, name) {\r\n return {\r\n metaName: name,\r\n className: value,\r\n }\r\n });\r\n }\r\n\r\n var classes = [];\r\n\r\n mapping.forEach(function(flag) {\r\n var isFlagSet = flag.customFunction || Librarian.Utils.doesFlaggingMetaMatch;\r\n if (isFlagSet(data, flag)) {\r\n classes.push(flag.className);\r\n }\r\n });\r\n\r\n return classes;\r\n },\r\n doesFlaggingMetaMatch: function(data, flag) {\r\n if (data.contenttype == Librarian.contentType.category && !Librarian.flagging.showOnCategory)\r\n return false;\r\n\r\n var metaName = flag.metaName;\r\n var metaValue = (flag.metaValue || \"true\").toLowerCase();\r\n\r\n var value = Librarian.Utils.getField(data, metaName);\r\n if (value == null)\r\n return false;\r\n\r\n var values = value.toString().toLowerCase().split(';');\r\n\r\n return values.contains(metaValue);\r\n },\r\n getField: function(data, fieldName, defaultValue) {\r\n if (!data)\r\n return defaultValue;\r\n\r\n var fields = data.extrafields || data.attributes;\r\n if (!fields)\r\n return defaultValue;\r\n\r\n // Also look for field with no spaces (e.g. from V_SearchFiles)\r\n var fieldNameNoSpaces = fieldName.replaceAll(\" \", \"\");\r\n\r\n for (var key in fields) {\r\n if (!fields.hasOwnProperty(key))\r\n continue;\r\n\r\n if (key.equalsIgnoreCase(fieldName) || key.equalsIgnoreCase(fieldNameNoSpaces))\r\n return fields[key];\r\n }\r\n\r\n return defaultValue;\r\n },\r\n getHashByName: function (name) {\r\n if (!name) {\r\n return null;\r\n }\r\n\r\n var data = this.getHash().parseQueryString() || {};\r\n\r\n return data[name];\r\n },\r\n openLibraryTreePanel: function () {\r\n $(\"sideColumn\").setStyle(\"display\", \"block\");\r\n $(\"sideColumn_handle_icon\").setStyle(\"display\", \"block\");\r\n\r\n if (sideColumn.isCollapsed) {\r\n if (sideColumn.handleIconEl) { sideColumn.handleIconEl.click(); }\r\n else { sideColumn.columnToggle(); }\r\n }\r\n },\r\n inIframe: function () {\r\n try {\r\n return window.self !== window.top;\r\n } catch (e) {\r\n return true;\r\n }\r\n },\r\n getFormData: function (query) {\r\n var vars = query.split(/[&;]/),\r\n object = {};\r\n\r\n if (!vars.length) return object;\r\n\r\n vars.each(function (val) {\r\n var kv = val.split('='),\r\n value = decodeURIComponent(kv[1]).trim(),\r\n keys = decodeURIComponent(kv[0]).replace(/\\[\\]/g, '').match(/([^\\]\\[]+|(\\B)(?=\\]))/g),\r\n obj = object;\r\n\r\n if (!keys) return;\r\n keys.each(function (key, i) {\r\n var current = obj[key];\r\n\r\n if (i < keys.length - 1) { obj = obj[key] = current || {}; }\r\n else if (typeOf(current) == 'array') current.push(value);\r\n else obj[key] = current != null ? [current, value] : value;\r\n });\r\n });\r\n\r\n return object;\r\n },\r\n getQueryString: function (params) {\r\n if (!params)\r\n return \"\";\r\n\r\n if (typeOf(params) == \"array\")\r\n params = params.join(\"&\");\r\n else if (typeOf(params) == \"object\")\r\n params = Object.toQueryString(params);\r\n\r\n return params.toString();\r\n },\r\n textToHtml: function(text) {\r\n var lines = text.split(\"\\n\");\r\n\r\n return lines.map(function(line) {\r\n return Librarian.Utils.escapeHtml(line);\r\n }).join(\"
\");\r\n },\r\n escapeHtml: function(text) {\r\n return text.escapeHtml();\r\n },\r\n getDropdownFilter: function(value) {\r\n if (!value)\r\n return null;\r\n\r\n var variations = [];\r\n\r\n variations.push(value);\r\n variations.push(\"%;\" + value);\r\n variations.push(value + \";%\");\r\n variations.push(\"%;\" + value + \";%\");\r\n\r\n return variations.join(\",\");\r\n },\r\n hasHtml5UploadSupport: function () {\r\n return window.FormData !== undefined;\r\n },\r\n\r\n getUserSetting: function(name) {\r\n var value = null;\r\n\r\n try {\r\n value = localStorage.getItem(name);\r\n }\r\n catch (error) {\r\n console.error(\"Could not get user setting: \" + name + \"\\n\" + error);\r\n }\r\n\r\n return value;\r\n },\r\n\r\n setUserSetting: function(name, value) {\r\n if (value != null) {\r\n try {\r\n localStorage.setItem(name, value);\r\n }\r\n catch (error) {\r\n console.error(\"Could not set user setting: \" + name + \"\\n\" + error);\r\n }\r\n }\r\n else\r\n Librarian.Utils.deleteUserSetting(name);\r\n },\r\n\r\n deleteUserSetting: function(name) {\r\n try {\r\n localStorage.removeItem(name);\r\n }\r\n catch (error) {\r\n console.error(\"Could not delete user setting: \" + name + \"\\n\" + error);\r\n }\r\n },\r\n\r\n validatePasswordComplexity: function (password) {\r\n var result = [];\r\n var validPassword = true;\r\n\r\n if (Librarian.passwordComplexityRules != null) {\r\n Librarian.passwordComplexityRules.forEach(function (rule) {\r\n var regex = new RegExp(rule.regex);\r\n var success = password.match(regex) != null;\r\n \r\n result.push({\r\n label: rule.label,\r\n success: success\r\n });\r\n\r\n if (!success) {\r\n validPassword = false;\r\n }\r\n });\r\n }\r\n\r\n return {\r\n validPassword: validPassword,\r\n result: result\r\n };\r\n },\r\n\r\n addPerformanceTime: function(label, endTime) {\r\n var startTime = window.performance.timing.navigationStart;\r\n\r\n if (!endTime)\r\n endTime = new Date();\r\n\r\n var seconds = (endTime - startTime) / 1000;\r\n\r\n Librarian.performanceTimes[label] = seconds;\r\n\r\n if (Librarian.logPerformanceTimes)\r\n console.log(label + \": \" + seconds + \" s\");\r\n }\r\n };\r\n}\r\n\r\nFunction.implement({\r\n // Returns a function with default arguments, and event arguments\r\n partial: function () {\r\n var self = this,\r\n args = Array.prototype.slice.call(arguments);\r\n return function () {\r\n var allArguments = args.concat(Array.prototype.slice.call(arguments));\r\n return self.apply(this, allArguments);\r\n };\r\n }\r\n});\r\n\r\n// Add functions to Elements and Document\r\n(function () {\r\n function _addEvent(fn, bindObj, eventName) {\r\n if (bindObj)\r\n this.addEvent(eventName, fn.bind(bindObj));\r\n else\r\n this.addEvent(eventName, fn);\r\n }\r\n\r\n function _removeEvent(fn, bindObj, eventName) {\r\n if (typeof fn == \"function\") {\r\n if (bindObj)\r\n this.removeEvent(eventName, fn.bind(bindObj));\r\n else\r\n this.removeEvent(eventName, fn);\r\n }\r\n else\r\n this.removeEvents(eventName);\r\n }\r\n\r\n Element.implement({\r\n addOnKeyPress: function (keys, fn, bindObj) {\r\n keys = Array.from(keys);\r\n if (bindObj)\r\n fn = fn.bind(bindObj);\r\n\r\n var wrapperFn = function(e) {\r\n if (keys.contains(e.key) || keys.contains(e.keyCode))\r\n fn(e);\r\n }\r\n\r\n _addEvent.apply(this, [wrapperFn, bindObj, \"keypress\"]);\r\n },\r\n\r\n addOnDblClick: function (fn, bindObj) {\r\n if (!Librarian.isAppleProduct())\r\n _addEvent.apply(this, [fn, bindObj, \"dblclick\"]);\r\n _addEvent.apply(this, [fn, bindObj, \"tap\"]);\r\n },\r\n\r\n addOnClick: function (fn, bindObj) {\r\n if (!Librarian.isAppleProduct())\r\n _addEvent.apply(this, [fn, bindObj, \"click\"]);\r\n _addEvent.apply(this, [fn, bindObj, \"tap\"]);\r\n },\r\n\r\n removeOnClick: function (fn, bindObj) {\r\n if (!Librarian.isAppleProduct())\r\n _removeEvent.apply(this, [fn, bindObj, \"click\"]);\r\n _removeEvent.apply(this, [fn, bindObj, \"tap\"]);\r\n },\r\n\r\n makeUnselectable: function () {\r\n if (this.nodeType == 1) {\r\n this.unselectable = true;\r\n if (typeof this.setAttribute == \"function\")\r\n this.setAttribute(\"unselectable\", \"on\");\r\n }\r\n\r\n var child = $(this.firstChild);\r\n while (child) {\r\n if (typeof child.makeUnselectable == \"function\")\r\n child.makeUnselectable();\r\n child = $(child.nextSibling);\r\n }\r\n },\r\n\r\n getRight: function () {\r\n return this.getLeft() + this.getWidth();\r\n },\r\n\r\n getBottom: function () {\r\n return this.getTop() + this.getHeight();\r\n }\r\n });\r\n\r\n Document.implement({\r\n addOnKeyPress: function (fn, bindObj) {\r\n var eventName = (Browser.Engine.trident || Browser.Engine.webkit || Browser.Engine.gecko) ? \"keydown\" : \"keypress\";\r\n\r\n _addEvent.apply(this, [fn, bindObj, eventName]);\r\n },\r\n\r\n removeOnKeyPress: function () {\r\n if (Browser.Engine.trident || Browser.Engine.webkit || Browser.Engine.gecko)\r\n this.removeEvents(\"keydown\");\r\n else\r\n this.removeEvents(\"keypress\");\r\n }\r\n });\r\n})();","AuthHandler = new Class({\r\n Binds: [\"parseQueryString\", \"isSsoEnabled\", \"getSamlRequest\", \"processSamlRequest\"],\r\n\r\n queryString: \"\",\r\n\r\n initialize: function() {\r\n var params = this.parseQueryString();\r\n var enabled = this.isSsoEnabled(params.sso);\r\n\r\n if (enabled && Librarian.features.sso.load)\r\n this.getSamlRequest();\r\n else {\r\n $$(\".loginpanel\").show();\r\n $$(\".loadingMessage\").hide();\r\n }\r\n },\r\n\r\n parseQueryString: function () {\r\n var search = (window.location.search || '').substring(1),\r\n hash = (window.location.hash || '');\r\n\r\n this.queryString = search + hash;\r\n\r\n return search.parseQueryString();\r\n },\r\n\r\n isSsoEnabled: function(ssoValue) {\r\n var enabled = Librarian.sso.enabledByDefault;\r\n if (window.location.host == \"localhost\")\r\n enabled = false;\r\n\r\n if (ssoValue)\r\n enabled = ssoValue.trim().toLowerCase() == \"true\";\r\n\r\n return enabled;\r\n },\r\n\r\n getSamlRequest: function() {\r\n var request = new Request.JSON({\r\n url: \"SamlAuth.ashx?mode=getRequest&out=json\",\r\n method: \"get\",\r\n noCache: true,\r\n onSuccess: this.processSamlRequest.bind(this)\r\n });\r\n\r\n request.send();\r\n },\r\n\r\n processSamlRequest: function(responseObj) {\r\n if (!responseObj || !responseObj.Target)\r\n return;\r\n\r\n var form = new Element(\"form\", {\r\n method: \"POST\",\r\n action: responseObj.Target\r\n }).inject(document.body);\r\n\r\n var samlRequest = new Element(\"input[type=hidden]\", {\r\n name: \"SAMLRequest\",\r\n value: responseObj.RequestString\r\n }).inject(form);\r\n\r\n var relayState = new Element(\"input[type=hidden]\", {\r\n name: \"RelayState\",\r\n value: this.queryString\r\n }).inject(form);\r\n\r\n form.submit();\r\n }\r\n});\r\n\r\nwindow.addEvent(\"load\", function() {\r\n Librarian.authHandler = new AuthHandler();\r\n});","var usernameSetting = \"webclient.login.username\",\r\n agreeSetting = \"webclient.login.hasagreed\",\r\n agreeSettingExp = \"webclient.login.agreeexp\";\r\n\r\nwindow.addEvent(\"load\", function() {\r\n initialize();\r\n});\r\n\r\ninitialize = function() {\r\n loadConfig();\r\n setupLoginForm();\r\n setupChangePassForm();\r\n setupForgotPass();\r\n setupUserAgreement();\r\n\r\n var ssoLoginButton = $(\"ssoLoginButton\");\r\n if (ssoLoginButton)\r\n ssoLoginButton.addOnClick(Librarian.authHandler.getSamlRequest);\r\n\r\n var copyrightYearEl = $(\"copyrightYear\");\r\n if (copyrightYearEl)\r\n copyrightYearEl.set(\"text\", new Date().getFullYear());\r\n\r\n if (Librarian.profile.enforcePasswordComplexity) {\r\n getPasswordComplexityRules();\r\n }\r\n\r\n if (Librarian.features.metroui.load) {\r\n var buttonEls = $$(\"input[type=button]\");\r\n for (var i = buttonEls.length; i--;)\r\n buttonEls[i].addClass(\"pure-button pure-button-primary\");\r\n }\r\n};\r\n\r\nloadConfig = function() {\r\n if (Librarian.features.config.load) {\r\n Librarian.Config.load(function() {\r\n $(document.body).show();\r\n });\r\n }\r\n else {\r\n $(document.body).show();\r\n }\r\n}\r\n\r\n// #region Login\r\n\r\nsetupLoginForm = function() {\r\n var loginFormEl = $(\"loginForm\");\r\n if (loginFormEl) {\r\n loginFormEl.reset();\r\n\r\n var savedUsername = Librarian.Utils.getUserSetting(usernameSetting);\r\n if (savedUsername) {\r\n // Set the email value\r\n loginFormEl.email.value = savedUsername;\r\n // Check the remember box\r\n loginFormEl.saveinfo.checked = true;\r\n // Focus on the password box\r\n if (loginFormEl.password && $(loginFormEl.password).isVisible())\r\n loginFormEl.password.focus();\r\n }\r\n // Otherwise focus on the email box\r\n else if (loginFormEl.email && $(loginFormEl.email).isVisible())\r\n loginFormEl.email.focus();\r\n\r\n loginFormEl.addOnKeyPress(\"enter\", onSubmit);\r\n }\r\n\r\n var itemEl = $(\"submitButton\");\r\n if (itemEl) {\r\n itemEl.addOnClick(onSubmit);\r\n }\r\n}\r\n\r\nonSubmit = function(e) {\r\n e.preventDefault();\r\n\r\n var loginFormEl = $(\"loginForm\");\r\n if (loginFormEl.hasClass(\"disabled\"))\r\n return;\r\n\r\n clearErrors();\r\n\r\n var itemEl = $(\"resetPassPanel\");\r\n if (itemEl)\r\n itemEl.hide();\r\n\r\n if (!loginFormEl.email.value || !loginFormEl.password.value) {\r\n toggleError(\"passError\", true);\r\n return;\r\n }\r\n\r\n if (loginFormEl.saveinfo.checked) \r\n Librarian.Utils.setUserSetting(usernameSetting, loginFormEl.email.value);\r\n else\r\n Librarian.Utils.deleteUserSetting(usernameSetting);\r\n\r\n disableForm(loginFormEl, true);\r\n\r\n logon();\r\n};\r\n\r\nlogon = function(params) {\r\n var credentials = getCredentials();\r\n\r\n var session = new Librarian.Session();\r\n session.onLogon = onLogonSuccess;\r\n session.onFailure = onLogonFailure;\r\n\r\n session.logon(credentials.username, credentials.password, params);\r\n};\r\n\r\ngetCredentials = function() {\r\n var loginFormEl = $(\"loginForm\");\r\n\r\n return {\r\n username: loginFormEl.email.value, \r\n password: loginFormEl.password.value\r\n };\r\n}\r\n\r\nonLogonSuccess = function(sessionInfo) {\r\n var changePassEl = $(\"changePassPanel\"),\r\n complexityEl = $(\"passComplexity\"),\r\n passRequirementsEl = $(\"passwordRequirementsWrapper\");\r\n\r\n if (sessionInfo.UserInfo.LoginMask == 1) {\r\n if (changePassEl)\r\n changePassEl.show();\r\n\r\n if (complexityEl)\r\n complexityEl.show();\r\n\r\n if (passRequirementsEl)\r\n passRequirementsEl.show();\r\n\r\n return;\r\n }\r\n\r\n if (changePassEl) \r\n changePassEl.hide();\r\n\r\n if (complexityEl)\r\n itemEl.hide();\r\n\r\n loadLibraryPage();\r\n};\r\n\r\nonLogonFailure = function(xhr) {\r\n if (xhr.status == 403)\r\n toggleError(\"restrictedAccess\", true);\r\n else if (Librarian.Session.isMfaRequired(xhr)) {\r\n handleMFA(xhr.responseText);\r\n return;\r\n }\r\n else\r\n toggleError(\"passError\", true);\r\n\r\n var itemEl = $(\"changePassPanel\");\r\n if (itemEl)\r\n itemEl.hide();\r\n\r\n itemEl = $(\"passComplexity\");\r\n if (itemEl)\r\n itemEl.hide();\r\n\r\n disableForm(\"loginForm\", false);\r\n};\r\n\r\nloadLibraryPage = function(forceAgree) {\r\n if (!checkUserAgreement(forceAgree))\r\n return;\r\n\r\n var url = \"library.htm?\" + Librarian.buildVersion + window.location.hash;\r\n\r\n window.open(url, \"_self\");\r\n};\r\n\r\n// #endregion\r\n\r\n// #region MFA\r\n\r\nhandleMFA = function(responseText) {\r\n var mfaInfo = JSON.parse(responseText);\r\n var credentials = getCredentials();\r\n\r\n var container = $(\"loginMfaContainer\");\r\n if (container)\r\n return;\r\n\r\n var loginPanel = document.getElement(\".loginpanel\");\r\n\r\n container = new Element(\"div\", {\r\n id: \"loginMfaContainer\"\r\n }).inject(loginPanel);\r\n\r\n var mfaPanel = new Librarian.Session.MFAPanel({\r\n container: container,\r\n mfaInfo: mfaInfo,\r\n credentials: credentials,\r\n onSuccess: onMfaSuccess\r\n });\r\n};\r\n\r\nonMfaSuccess = function(sessionInfo) {\r\n var container = $(\"loginMfaContainer\");\r\n if (container)\r\n container.hide();\r\n\r\n onLogonSuccess(sessionInfo);\r\n}\r\n\r\n// #endregion\r\n\r\n// #region Update Password\r\n\r\nsetupChangePassForm = function() {\r\n var changePassFormEl = $(\"changePassForm\");\r\n if (changePassFormEl) {\r\n changePassFormEl.reset();\r\n\r\n changePassFormEl.addOnKeyPress(\"enter\", updateUserInfo);\r\n }\r\n\r\n var itemEl = $(\"updateButton\");\r\n if (itemEl) {\r\n itemEl.addOnClick(updateUserInfo);\r\n }\r\n}\r\n\r\nupdateUserInfo = function(e) {\r\n e.preventDefault();\r\n\r\n var changePassFormEl = $(\"changePassForm\");\r\n if (changePassFormEl.hasClass(\"disabled\"))\r\n return;\r\n\r\n var updatePasswordEl = $(\"newPass\"),\r\n updatePassword2El = $(\"newPassConfirm\"),\r\n itemEl = $(\"resetPassPanel\");\r\n if (itemEl)\r\n itemEl.hide();\r\n\r\n itemEl = $(\"passComplexity\");\r\n if (itemEl)\r\n itemEl.hide();\r\n\r\n clearErrors();\r\n\r\n var updateErrorEl = $(\"newPassError\");\r\n // If passwords are empty, show error message\r\n if ((updatePasswordEl.value.length == 0) || (updatePassword2El.value.length == 0)) {\r\n if (updateErrorEl)\r\n updateErrorEl.show(\"table-row\");\r\n return;\r\n }\r\n if (updateErrorEl)\r\n updateErrorEl.hide();\r\n\r\n updateErrorEl = $(\"passMatchError\");\r\n // Compare passwords and show error if no match\r\n if (updatePasswordEl.value != updatePassword2El.value) {\r\n if (updateErrorEl)\r\n updateErrorEl.show(\"table-row\");\r\n return;\r\n }\r\n if (updateErrorEl)\r\n updateErrorEl.hide();\r\n\r\n updateErrorEl = $(\"passStrengthError\");\r\n if ((typeof Librarian.passwordStrengthRegex == \"string\") && (Librarian.passwordStrengthRegex.length > 0)) {\r\n var match = new RegExp(Librarian.passwordStrengthRegex).test(updatePasswordEl.value);\r\n if (!match) {\r\n if (updateErrorEl)\r\n updateErrorEl.show(\"table-row\");\r\n return;\r\n }\r\n }\r\n else if (Librarian.profile.enforcePasswordComplexity) {\r\n var validationResult = Librarian.Utils.validatePasswordComplexity(updatePasswordEl.value);\r\n renderPasswordComplexity(validationResult.result);\r\n\r\n if (!validationResult.validPassword) {\r\n return;\r\n }\r\n }\r\n if (updateErrorEl)\r\n updateErrorEl.hide();\r\n\r\n // Check existance of security Q&A\r\n var securityQuestionEl = $(\"securityQuestion\"),\r\n securityAnswerEl = $(\"securityAnswer\"),\r\n securityEmptyEl = $(\"securityError\");\r\n\r\n // Make sure that the security question and answe were filled out\r\n if ((securityAnswerEl.value.length == 0) || (securityQuestionEl.value.length == 0)) {\r\n securityEmptyEl.show();\r\n return;\r\n }\r\n securityEmptyEl.hide();\r\n\r\n // Hide the error message again so that the\r\n // user knows if the update fails multiple times.\r\n updateErrorEl = $(\"updateError\");\r\n if (updateErrorEl)\r\n updateErrorEl.hide();\r\n\r\n disableForm(changePassFormEl, true);\r\n\r\n var session = new Librarian.Session();\r\n session.onUpdateComplete = onUpdatePasswordSuccess;\r\n session.onFailure = onUpdatePasswordFailure;\r\n\r\n var loginFormEl = $(\"loginForm\");\r\n session.changePassword(loginFormEl.password.value, updatePasswordEl.value, securityQuestionEl.value, securityAnswerEl.value);\r\n};\r\n\r\nonUpdatePasswordSuccess = function() {\r\n loadLibraryPage();\r\n};\r\n\r\nonUpdatePasswordFailure = function() {\r\n // Display the error message\r\n var itemEl = $(\"updateError\");\r\n if (itemEl)\r\n itemEl.show(\"table-row\");\r\n\r\n disableForm(changePassFormEl, false);\r\n};\r\n\r\n// #endregion\r\n\r\n// #region Forgot Password\r\n\r\nsetupForgotPass = function() {\r\n var forgotPassEl = $(\"forgotPass\");\r\n if (!forgotPassEl)\r\n return;\r\n\r\n forgotPassEl.addOnClick(onClickForgotPass);\r\n}\r\n\r\nonClickForgotPass = function() {\r\n var loginFormEl = $(\"loginForm\"),\r\n username = loginFormEl.email.value;\r\n\r\n clearErrors();\r\n\r\n if (!username) {\r\n toggleError(\"resetNoUserError\", true);\r\n return;\r\n }\r\n\r\n var session = new Librarian.Session();\r\n\r\n session.sendResetPassword(username);\r\n}\r\n\r\n// #endregion\r\n\r\n// #region User Agreement\r\n\r\nsetupUserAgreement = function() {\r\n var agreeEl = $(\"agreeDiv\");\r\n if (!agreeEl)\r\n return;\r\n\r\n var agreeButton = $(\"agreeButton\");\r\n if (agreeButton)\r\n agreeButton.addOnClick(agree);\r\n\r\n var cancelAgreeButton = $(\"cancelAgreeButton\");\r\n if (cancelAgreeButton)\r\n cancelAgreeButton.addOnClick(cancelAgree);\r\n}\r\n\r\ncheckUserAgreement = function(forceAgree) {\r\n var agreeEl = $(\"agreeDiv\");\r\n if (!agreeEl)\r\n return true;\r\n\r\n if (forceAgree)\r\n return true;\r\n\r\n var hasAgreed = Librarian.Utils.getUserSetting(agreeSetting);\r\n var isExpired = false;\r\n\r\n if (Librarian.agreeStateExpDays) {\r\n isExpired = Librarian.Utils.getUserSetting(agreeSettingExp);\r\n isExpired = Librarian.Utils.getUTCDateValue(isExpired) < Librarian.Utils.getUTCDateValue(new Date());\r\n }\r\n \r\n if (hasAgreed && !isExpired)\r\n return true;\r\n\r\n if (typeof loadAgreementPage === \"function\")\r\n loadAgreementPage();\r\n else\r\n agreeEl.show();\r\n\r\n var itemEl = $(\"loginForm\");\r\n if (itemEl)\r\n itemEl.hide();\r\n\r\n itemEl = $(\"resetPassPanel\");\r\n if (itemEl)\r\n itemEl.hide();\r\n\r\n itemEl = $(\"changePassPanel\");\r\n if (itemEl)\r\n itemEl.hide();\r\n\r\n itemEl = $(\"passComplexity\");\r\n if (itemEl)\r\n itemEl.hide();\r\n\r\n return false;\r\n}\r\n\r\nagree = function() {\r\n if (Librarian.saveAgreeState)\r\n Librarian.Utils.setUserSetting(agreeSetting, true);\r\n if (Librarian.agreeStateExpDays) {\r\n var expire = new Date();\r\n expire.setDate(expire.getDate() + Librarian.agreeStateExpDays);\r\n Librarian.Utils.setUserSetting(agreeSettingExp, expire);\r\n }\r\n\r\n loadLibraryPage(true);\r\n};\r\n\r\ncancelAgree = function () {\r\n var itemEl = $(\"agreeDiv\");\r\n if (itemEl) {\r\n itemEl.hide();\r\n }\r\n\r\n var loginFormEl = $(\"loginForm\");\r\n if (loginFormEl) {\r\n loginFormEl.show();\r\n\r\n disableForm(loginFormEl, false);\r\n }\r\n};\r\n\r\n// #endregion\r\n\r\n// #region Password Complexity\r\n\r\ngetPasswordComplexityRules = function () {\r\n var directory = Librarian.profile.customPasswordComplexity ? Librarian.path.getLibraryPath() : Librarian.path.getLayoutsPath() +\r\n \"core/\";\r\n var url = directory + \"passwordcomplexity.json\";\r\n new Request.JSON({\r\n method: \"get\",\r\n url: url,\r\n noCache: true,\r\n onSuccess: function (data) {\r\n if (data) {\r\n Librarian.passwordComplexityRules = data;\r\n renderPasswordComplexity(Librarian.passwordComplexityRules);\r\n }\r\n },\r\n onFailure: function (err) {\r\n console.log(err);\r\n }\r\n }).send();\r\n\r\n /*\r\n var url = Librarian.path.getConfigUrl(\"getpasscomplexityrules\") + \"&out=cjson\";\r\n new Request.JSON({\r\n method: \"get\",\r\n url: url,\r\n noCache: true,\r\n onSuccess: function (data) {\r\n if (data) {\r\n Librarian.passwordComplexityRules = data;\r\n renderPasswordComplexity($(\"resetPasswordRequirements\"), Librarian.passwordComplexityRules);\r\n renderPasswordComplexity($(\"changePasswordRequirements\"), Librarian.passwordComplexityRules);\r\n }\r\n },\r\n onFailure: function (err) {\r\n console.log(err);\r\n }\r\n }).send();*/\r\n}\r\n\r\nrenderPasswordComplexity = function (validationResult) {\r\n var errorEl = $(\"passwordRequirements\");\r\n\r\n if (errorEl == null) {\r\n var passwordComplexityRequirementsEl = new Element(\"div\", {\r\n \"id\": \"passwordRequirementsWrapper\"\r\n });\r\n\r\n passwordComplexityRequirementsEl.set(\"html\",\r\n \"
\\\r\n Password Requirements:\\\r\n
\\\r\n
\");\r\n\r\n var forgotPassEl = $(document.body).getElement(\".forgotpass\");\r\n passwordComplexityRequirementsEl.injectAfter(forgotPassEl);\r\n\r\n errorEl = $(\"passwordRequirements\");\r\n }\r\n\r\n var rulesEl = new Element(\"ul\", {\r\n class: \"password-complexity-rules\"\r\n });\r\n\r\n validationResult.forEach(function (ruleResult) {\r\n var ruleEl = new Element(\"li\", {\r\n class: \"password-complexity-rule\",\r\n });\r\n var stateEl = new Element(\"span\", {\r\n class: \"password-complexity-state\"\r\n });\r\n var textEl = new Element(\"span\", {\r\n class: \"password-complexity-rule-label\",\r\n text: ruleResult.label\r\n });\r\n ruleEl.grab(stateEl);\r\n ruleEl.grab(textEl);\r\n\r\n if (ruleResult.success === true) {\r\n stateEl.addClass(\"success\");\r\n }\r\n else if (ruleResult.success === false) {\r\n stateEl.addClass(\"fail\");\r\n }\r\n\r\n rulesEl.grab(ruleEl);\r\n });\r\n\r\n if (errorEl) {\r\n errorEl.empty();\r\n errorEl.grab(rulesEl);\r\n errorEl.show();\r\n }\r\n}\r\n\r\n// #endregion\r\n\r\n// #region Helpers\r\n\r\ndisableForm = function(id, disabled) {\r\n var formEl = $(id);\r\n if (!formEl)\r\n return;\r\n\r\n formEl.toggleClass(\"disabled\", disabled);\r\n\r\n var inputEls = formEl.getElements(\"input\");\r\n\r\n inputEls.forEach(function(inputEl) {\r\n inputEl.disabled = disabled;\r\n });\r\n}\r\n\r\ntoggleError = function(id, show) {\r\n var errorEl = $(id);\r\n if (!errorEl)\r\n return;\r\n\r\n errorEl.toggle(show);\r\n\r\n if (show) {\r\n var wrapperEl = $(\"errorWrapper\");\r\n if (wrapperEl)\r\n wrapperEl.show();\r\n }\r\n};\r\n\r\nclearErrors = function() {\r\n toggleError(\"passError\", false);\r\n toggleError(\"badUserError\", false);\r\n toggleError(\"resetNoUserError\", false);\r\n toggleError(\"resetSuccess\", false);\r\n\r\n var itemEl = $(\"errorWrapper\");\r\n if (itemEl)\r\n itemEl.hide();\r\n}\r\n\r\n// #endregion\r\n\r\n// If the library is set to force secure but it's not currently secure, redirect to the HTTPS page\r\nif (Librarian.forceSecure && !Librarian.secure)\r\n window.open(window.location.href.replace(\"http:\", \"https:\"), \"_self\");\r\n\r\nif (!Librarian.newLoginStyle) {\r\n // Load these styles so the login screen gets adapted to the new styles\r\n if (Librarian.features.metroui.load)\r\n Librarian.addStyle(Librarian.path.getDefaultThemePath() + \"css/Metro.css\");\r\n if (Librarian.features.darkui.load)\r\n Librarian.addStyle(Librarian.path.getDefaultThemePath() + \"css/Dark.css\");\r\n}\r\n\r\nLibrarian.addStyle(Librarian.path.getDefaultThemePath() + \"css/PasswordComplexity.css\");\r\n","Librarian.Config = {\r\n libraryTemplate: null,\r\n config: null,\r\n\r\n load: function (onComplete) {\r\n Librarian.Config.chain = new Chain();\r\n Librarian.Config.chain.chain(\r\n Librarian.Config.loadConfig,\r\n Librarian.Config.loadLibraryTemplate,\r\n Librarian.Config.applyLibraryStyles,\r\n Librarian.Config.applyLogo,\r\n function () {\r\n if (onComplete) {\r\n onComplete();\r\n }\r\n\r\n Librarian.Config.chain.callChain();\r\n }\r\n ).callChain();\r\n },\r\n\r\n loadConfig: function () {\r\n var url = Librarian.path.getConfigUrl(\"getbrandingfile\") + \"&name=LibraryStyles.json\";\r\n\r\n new Request.JSON({\r\n url: url,\r\n method: \"get\",\r\n onSuccess: function (config) {\r\n Librarian.Config.config = config;\r\n Librarian.Config.chain.callChain();\r\n },\r\n onFailure: function() {\r\n Librarian.Config.chain.callChain();\r\n }\r\n }).send();\r\n },\r\n\r\n loadLibraryTemplate: function () {\r\n var url = Librarian.path.getLayoutsPath() + \"core/config/libraryTemplate.css\";\r\n\r\n var request = new Request({\r\n url: url,\r\n method: \"get\",\r\n format: \"text\",\r\n onSuccess: function (template) {\r\n Librarian.Config.libraryTemplate = template;\r\n Librarian.Config.chain.callChain();\r\n },\r\n onFailure: function () {\r\n Librarian.Config.chain.callChain();\r\n }\r\n });\r\n\r\n request.send();\r\n },\r\n\r\n applyLibraryStyles: function () {\r\n var libraryCss = Librarian.Config.libraryTemplate;\r\n var libraryStyles = Librarian.Config.config;\r\n\r\n if (libraryCss != null && libraryStyles != null) {\r\n Object.each(libraryStyles, function (val, key) {\r\n var placeHolder = \"\\\\[\" + key + \"\\\\]\";\r\n var regEx = new RegExp(placeHolder, \"g\");\r\n libraryCss = libraryCss.replace(regEx, val);\r\n });\r\n\r\n var id = \"library-branding-css\";\r\n var css = document.getElementById(id);\r\n\r\n if (css != null) {\r\n css.remove();\r\n }\r\n\r\n css = document.createElement(\"style\");\r\n css.type = \"text/css\";\r\n css.id = \"library-branding-css\";\r\n if (\"textContent\" in css)\r\n css.textContent = libraryCss;\r\n else\r\n css.innerText = libraryCss;\r\n document.body.appendChild(css);\r\n }\r\n\r\n Librarian.Config.chain.callChain();\r\n },\r\n\r\n applyLogo: function () {\r\n var url = Librarian.path.getConfigUrl(\"getbrandingfile\") + \"&name=LibraryLogo\";\r\n\r\n // Library Logo\r\n var headerLogoEl = $(\"headerLogo\");\r\n if (headerLogoEl != null) {\r\n headerLogoEl.set(\"src\", url);\r\n }\r\n \r\n //Login Logo\r\n var loginHeaderLogoEl = $(document.body).getElement(\".header img\");\r\n if (loginHeaderLogoEl != null) {\r\n loginHeaderLogoEl.set(\"src\", url);\r\n }\r\n\r\n Librarian.Config.chain.callChain();\r\n }\r\n};"]}