Sindbad~EG File Manager
{"version":3,"file":"view.min.js","sources":["../src/view.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Manage the courses view for the overview block.\n *\n * @copyright 2018 Bas Brands <bas@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n[\n 'jquery',\n 'block_myoverview/repository',\n 'core/paged_content_factory',\n 'core/pubsub',\n 'core/custom_interaction_events',\n 'core/notification',\n 'core/templates',\n 'core_course/events',\n 'block_myoverview/selectors',\n 'core/paged_content_events',\n 'core/aria',\n],\nfunction(\n $,\n Repository,\n PagedContentFactory,\n PubSub,\n CustomEvents,\n Notification,\n Templates,\n CourseEvents,\n Selectors,\n PagedContentEvents,\n Aria\n) {\n\n var SELECTORS = {\n COURSE_REGION: '[data-region=\"course-view-content\"]',\n ACTION_HIDE_COURSE: '[data-action=\"hide-course\"]',\n ACTION_SHOW_COURSE: '[data-action=\"show-course\"]',\n ACTION_ADD_FAVOURITE: '[data-action=\"add-favourite\"]',\n ACTION_REMOVE_FAVOURITE: '[data-action=\"remove-favourite\"]',\n FAVOURITE_ICON: '[data-region=\"favourite-icon\"]',\n ICON_IS_FAVOURITE: '[data-region=\"is-favourite\"]',\n ICON_NOT_FAVOURITE: '[data-region=\"not-favourite\"]',\n PAGED_CONTENT_CONTAINER: '[data-region=\"page-container\"]'\n\n };\n\n var TEMPLATES = {\n COURSES_CARDS: 'block_myoverview/view-cards',\n COURSES_LIST: 'block_myoverview/view-list',\n COURSES_SUMMARY: 'block_myoverview/view-summary',\n NOCOURSES: 'core_course/no-courses'\n };\n\n var GROUPINGS = {\n GROUPING_ALLINCLUDINGHIDDEN: 'allincludinghidden',\n GROUPING_ALL: 'all',\n GROUPING_INPROGRESS: 'inprogress',\n GROUPING_FUTURE: 'future',\n GROUPING_PAST: 'past',\n GROUPING_FAVOURITES: 'favourites',\n GROUPING_HIDDEN: 'hidden'\n };\n\n var NUMCOURSES_PERPAGE = [12, 24, 48, 96, 0];\n\n var loadedPages = [];\n\n var courseOffset = 0;\n\n var lastPage = 0;\n\n var lastLimit = 0;\n\n var namespace = null;\n\n /**\n * Get filter values from DOM.\n *\n * @param {object} root The root element for the courses view.\n * @return {filters} Set filters.\n */\n var getFilterValues = function(root) {\n var courseRegion = root.find(Selectors.courseView.region);\n return {\n display: courseRegion.attr('data-display'),\n grouping: courseRegion.attr('data-grouping'),\n sort: courseRegion.attr('data-sort'),\n displaycategories: courseRegion.attr('data-displaycategories'),\n customfieldname: courseRegion.attr('data-customfieldname'),\n customfieldvalue: courseRegion.attr('data-customfieldvalue'),\n };\n };\n\n // We want the paged content controls below the paged content area.\n // and the controls should be ignored while data is loading.\n var DEFAULT_PAGED_CONTENT_CONFIG = {\n ignoreControlWhileLoading: true,\n controlPlacementBottom: true,\n persistentLimitKey: 'block_myoverview_user_paging_preference'\n };\n\n /**\n * Get enrolled courses from backend.\n *\n * @param {object} filters The filters for this view.\n * @param {int} limit The number of courses to show.\n * @return {promise} Resolved with an array of courses.\n */\n var getMyCourses = function(filters, limit) {\n\n return Repository.getEnrolledCoursesByTimeline({\n offset: courseOffset,\n limit: limit,\n classification: filters.grouping,\n sort: filters.sort,\n customfieldname: filters.customfieldname,\n customfieldvalue: filters.customfieldvalue\n });\n };\n\n /**\n * Get the container element for the favourite icon.\n *\n * @param {Object} root The course overview container\n * @param {Number} courseId Course id number\n * @return {Object} The favourite icon container\n */\n var getFavouriteIconContainer = function(root, courseId) {\n return root.find(SELECTORS.FAVOURITE_ICON + '[data-course-id=\"' + courseId + '\"]');\n };\n\n /**\n * Get the paged content container element.\n *\n * @param {Object} root The course overview container\n * @param {Number} index Rendered page index.\n * @return {Object} The rendered paged container.\n */\n var getPagedContentContainer = function(root, index) {\n return root.find('[data-region=\"paged-content-page\"][data-page=\"' + index + '\"]');\n };\n\n /**\n * Get the course id from a favourite element.\n *\n * @param {Object} root The favourite icon container element.\n * @return {Number} Course id.\n */\n var getCourseId = function(root) {\n return root.attr('data-course-id');\n };\n\n /**\n * Hide the favourite icon.\n *\n * @param {Object} root The favourite icon container element.\n * @param {Number} courseId Course id number.\n */\n var hideFavouriteIcon = function(root, courseId) {\n var iconContainer = getFavouriteIconContainer(root, courseId);\n\n var isFavouriteIcon = iconContainer.find(SELECTORS.ICON_IS_FAVOURITE);\n isFavouriteIcon.addClass('hidden');\n Aria.hide(isFavouriteIcon);\n\n var notFavourteIcon = iconContainer.find(SELECTORS.ICON_NOT_FAVOURITE);\n notFavourteIcon.removeClass('hidden');\n Aria.unhide(notFavourteIcon);\n };\n\n /**\n * Show the favourite icon.\n *\n * @param {Object} root The course overview container.\n * @param {Number} courseId Course id number.\n */\n var showFavouriteIcon = function(root, courseId) {\n var iconContainer = getFavouriteIconContainer(root, courseId);\n\n var isFavouriteIcon = iconContainer.find(SELECTORS.ICON_IS_FAVOURITE);\n isFavouriteIcon.removeClass('hidden');\n Aria.unhide(isFavouriteIcon);\n\n var notFavourteIcon = iconContainer.find(SELECTORS.ICON_NOT_FAVOURITE);\n notFavourteIcon.addClass('hidden');\n Aria.hide(notFavourteIcon);\n };\n\n /**\n * Get the action menu item\n *\n * @param {Object} root root The course overview container\n * @param {Number} courseId Course id.\n * @return {Object} The add to favourite menu item.\n */\n var getAddFavouriteMenuItem = function(root, courseId) {\n return root.find('[data-action=\"add-favourite\"][data-course-id=\"' + courseId + '\"]');\n };\n\n /**\n * Get the action menu item\n *\n * @param {Object} root root The course overview container\n * @param {Number} courseId Course id.\n * @return {Object} The remove from favourites menu item.\n */\n var getRemoveFavouriteMenuItem = function(root, courseId) {\n return root.find('[data-action=\"remove-favourite\"][data-course-id=\"' + courseId + '\"]');\n };\n\n /**\n * Add course to favourites\n *\n * @param {Object} root The course overview container\n * @param {Number} courseId Course id number\n */\n var addToFavourites = function(root, courseId) {\n var removeAction = getRemoveFavouriteMenuItem(root, courseId);\n var addAction = getAddFavouriteMenuItem(root, courseId);\n\n setCourseFavouriteState(courseId, true).then(function(success) {\n if (success) {\n PubSub.publish(CourseEvents.favourited, courseId);\n removeAction.removeClass('hidden');\n addAction.addClass('hidden');\n showFavouriteIcon(root, courseId);\n } else {\n Notification.alert('Starring course failed', 'Could not change favourite state');\n }\n return;\n }).catch(Notification.exception);\n };\n\n /**\n * Remove course from favourites\n *\n * @param {Object} root The course overview container\n * @param {Number} courseId Course id number\n */\n var removeFromFavourites = function(root, courseId) {\n var removeAction = getRemoveFavouriteMenuItem(root, courseId);\n var addAction = getAddFavouriteMenuItem(root, courseId);\n\n setCourseFavouriteState(courseId, false).then(function(success) {\n if (success) {\n PubSub.publish(CourseEvents.unfavorited, courseId);\n removeAction.addClass('hidden');\n addAction.removeClass('hidden');\n hideFavouriteIcon(root, courseId);\n } else {\n Notification.alert('Starring course failed', 'Could not change favourite state');\n }\n return;\n }).catch(Notification.exception);\n };\n\n /**\n * Get the action menu item\n *\n * @param {Object} root root The course overview container\n * @param {Number} courseId Course id.\n * @return {Object} The hide course menu item.\n */\n var getHideCourseMenuItem = function(root, courseId) {\n return root.find('[data-action=\"hide-course\"][data-course-id=\"' + courseId + '\"]');\n };\n\n /**\n * Get the action menu item\n *\n * @param {Object} root root The course overview container\n * @param {Number} courseId Course id.\n * @return {Object} The show course menu item.\n */\n var getShowCourseMenuItem = function(root, courseId) {\n return root.find('[data-action=\"show-course\"][data-course-id=\"' + courseId + '\"]');\n };\n\n /**\n * Hide course\n *\n * @param {Object} root The course overview container\n * @param {Number} courseId Course id number\n */\n var hideCourse = function(root, courseId) {\n var hideAction = getHideCourseMenuItem(root, courseId);\n var showAction = getShowCourseMenuItem(root, courseId);\n var filters = getFilterValues(root);\n\n setCourseHiddenState(courseId, true);\n\n // Remove the course from this view as it is now hidden and thus not covered by this view anymore.\n // Do only if we are not in \"All\" view mode where really all courses are shown.\n if (filters.grouping != GROUPINGS.GROUPING_ALLINCLUDINGHIDDEN) {\n hideElement(root, courseId);\n }\n\n hideAction.addClass('hidden');\n showAction.removeClass('hidden');\n };\n\n /**\n * Show course\n *\n * @param {Object} root The course overview container\n * @param {Number} courseId Course id number\n */\n var showCourse = function(root, courseId) {\n var hideAction = getHideCourseMenuItem(root, courseId);\n var showAction = getShowCourseMenuItem(root, courseId);\n var filters = getFilterValues(root);\n\n setCourseHiddenState(courseId, null);\n\n // Remove the course from this view as it is now shown again and thus not covered by this view anymore.\n // Do only if we are not in \"All\" view mode where really all courses are shown.\n if (filters.grouping != GROUPINGS.GROUPING_ALLINCLUDINGHIDDEN) {\n hideElement(root, courseId);\n }\n\n hideAction.removeClass('hidden');\n showAction.addClass('hidden');\n };\n\n /**\n * Set the courses hidden status and push to repository\n *\n * @param {Number} courseId Course id to favourite.\n * @param {Bool} status new hidden status.\n * @return {Promise} Repository promise.\n */\n var setCourseHiddenState = function(courseId, status) {\n\n // If the given status is not hidden, the preference has to be deleted with a null value.\n if (status === false) {\n status = null;\n }\n return Repository.updateUserPreferences({\n preferences: [\n {\n type: 'block_myoverview_hidden_course_' + courseId,\n value: status\n }\n ]\n });\n };\n\n /**\n * Reset the loadedPages dataset to take into account the hidden element\n *\n * @param {Object} root The course overview container\n * @param {Number} id The course id number\n */\n var hideElement = function(root, id) {\n var pagingBar = root.find('[data-region=\"paging-bar\"]');\n var jumpto = parseInt(pagingBar.attr('data-active-page-number'));\n\n // Get a reduced dataset for the current page.\n var courseList = loadedPages[jumpto];\n var reducedCourse = courseList.courses.reduce(function(accumulator, current) {\n if (id != current.id) {\n accumulator.push(current);\n }\n return accumulator;\n }, []);\n\n // Get the next page's data if loaded and pop the first element from it\n if (loadedPages[jumpto + 1] != undefined) {\n var newElement = loadedPages[jumpto + 1].courses.slice(0, 1);\n\n // Adjust the dataset for the reset of the pages that are loaded\n loadedPages.forEach(function(courseList, index) {\n if (index > jumpto) {\n var popElement = [];\n if (loadedPages[index + 1] != undefined) {\n popElement = loadedPages[index + 1].courses.slice(0, 1);\n }\n\n loadedPages[index].courses = $.merge(loadedPages[index].courses.slice(1), popElement);\n }\n });\n\n\n reducedCourse = $.merge(reducedCourse, newElement);\n }\n\n // Check if the next page is the last page and if it still has data associated to it\n if (lastPage == jumpto + 1 && loadedPages[jumpto + 1].courses.length == 0) {\n var pagedContentContainer = root.find('[data-region=\"paged-content-container\"]');\n PagedContentFactory.resetLastPageNumber($(pagedContentContainer).attr('id'), jumpto);\n }\n\n loadedPages[jumpto].courses = reducedCourse;\n\n // Reduce the course offset\n courseOffset--;\n\n // Render the paged content for the current\n var pagedContentPage = getPagedContentContainer(root, jumpto);\n renderCourses(root, loadedPages[jumpto]).then(function(html, js) {\n return Templates.replaceNodeContents(pagedContentPage, html, js);\n }).catch(Notification.exception);\n\n // Delete subsequent pages in order to trigger the callback\n loadedPages.forEach(function(courseList, index) {\n if (index > jumpto) {\n var page = getPagedContentContainer(root, index);\n page.remove();\n }\n });\n };\n\n /**\n * Set the courses favourite status and push to repository\n *\n * @param {Number} courseId Course id to favourite.\n * @param {Bool} status new favourite status.\n * @return {Promise} Repository promise.\n */\n var setCourseFavouriteState = function(courseId, status) {\n\n return Repository.setFavouriteCourses({\n courses: [\n {\n 'id': courseId,\n 'favourite': status\n }\n ]\n }).then(function(result) {\n if (result.warnings.length == 0) {\n loadedPages.forEach(function(courseList) {\n courseList.courses.forEach(function(course, index) {\n if (course.id == courseId) {\n courseList.courses[index].isfavourite = status;\n }\n });\n });\n return true;\n } else {\n return false;\n }\n }).catch(Notification.exception);\n };\n\n /**\n * Render the dashboard courses.\n *\n * @param {object} root The root element for the courses view.\n * @param {array} coursesData containing array of returned courses.\n * @return {promise} jQuery promise resolved after rendering is complete.\n */\n var renderCourses = function(root, coursesData) {\n\n var filters = getFilterValues(root);\n\n var currentTemplate = '';\n if (filters.display == 'card') {\n currentTemplate = TEMPLATES.COURSES_CARDS;\n } else if (filters.display == 'list') {\n currentTemplate = TEMPLATES.COURSES_LIST;\n } else {\n currentTemplate = TEMPLATES.COURSES_SUMMARY;\n }\n\n // Whether the course category should be displayed in the course item.\n coursesData.courses = coursesData.courses.map(function(course) {\n course.showcoursecategory = filters.displaycategories == 'on' ? true : false;\n return course;\n });\n\n if (coursesData.courses.length) {\n return Templates.render(currentTemplate, {\n courses: coursesData.courses,\n });\n } else {\n var nocoursesimg = root.find(Selectors.courseView.region).attr('data-nocoursesimg');\n return Templates.render(TEMPLATES.NOCOURSES, {\n nocoursesimg: nocoursesimg\n });\n }\n };\n\n /**\n * Return the callback to be passed to the subscribe event\n *\n * @param {Number} limit The paged limit that is passed through the event\n */\n var setLimit = function(limit) {\n this.find(Selectors.courseView.region).attr('data-paging', limit);\n };\n\n /**\n * Intialise the paged list and cards views on page load.\n * Returns an array of paged contents that we would like to handle here\n *\n * @param {object} root The root element for the courses view\n * @param {string} namespace The namespace for all the events attached\n */\n var registerPagedEventHandlers = function(root, namespace) {\n var event = namespace + PagedContentEvents.SET_ITEMS_PER_PAGE_LIMIT;\n PubSub.subscribe(event, setLimit.bind(root));\n };\n\n /**\n * Intialise the courses list and cards views on page load.\n *\n * @param {object} root The root element for the courses view.\n */\n var initializePagedContent = function(root) {\n namespace = \"block_myoverview_\" + root.attr('id') + \"_\" + Math.random();\n\n var pagingLimit = parseInt(root.find(Selectors.courseView.region).attr('data-paging'), 10);\n var itemsPerPage = NUMCOURSES_PERPAGE.map(function(value) {\n var active = false;\n if (value == pagingLimit) {\n active = true;\n }\n\n return {\n value: value,\n active: active\n };\n });\n\n // Filter out all pagination options which are too large for the amount of courses user is enrolled in.\n var totalCourseCount = parseInt(root.find(Selectors.courseView.region).attr('data-totalcoursecount'), 10);\n itemsPerPage = itemsPerPage.filter(function(pagingOption) {\n return pagingOption.value < totalCourseCount || pagingOption.value === 0;\n });\n\n var filters = getFilterValues(root);\n var config = $.extend({}, DEFAULT_PAGED_CONTENT_CONFIG);\n config.eventNamespace = namespace;\n\n var pagedContentPromise = PagedContentFactory.createWithLimit(\n itemsPerPage,\n function(pagesData, actions) {\n var promises = [];\n\n pagesData.forEach(function(pageData) {\n var currentPage = pageData.pageNumber;\n var limit = (pageData.limit > 0) ? pageData.limit : 0;\n\n // Reset local variables if limits have changed\n if (lastLimit != limit) {\n loadedPages = [];\n courseOffset = 0;\n lastPage = 0;\n }\n\n if (lastPage == currentPage) {\n // If we are on the last page and have it's data then load it from cache\n actions.allItemsLoaded(lastPage);\n promises.push(renderCourses(root, loadedPages[currentPage]));\n return;\n }\n\n lastLimit = limit;\n\n // Get 2 pages worth of data as we will need it for the hidden functionality.\n if (loadedPages[currentPage + 1] == undefined) {\n if (loadedPages[currentPage] == undefined) {\n limit *= 2;\n }\n }\n\n var pagePromise = getMyCourses(\n filters,\n limit\n ).then(function(coursesData) {\n var courses = coursesData.courses;\n var nextPageStart = 0;\n var pageCourses = [];\n\n // If current page's data is loaded make sure we max it to page limit\n if (loadedPages[currentPage] != undefined) {\n pageCourses = loadedPages[currentPage].courses;\n var currentPageLength = pageCourses.length;\n if (currentPageLength < pageData.limit) {\n nextPageStart = pageData.limit - currentPageLength;\n pageCourses = $.merge(loadedPages[currentPage].courses, courses.slice(0, nextPageStart));\n }\n } else {\n // When the page limit is zero, there is only one page of courses, no start for next page.\n nextPageStart = pageData.limit || false;\n pageCourses = (pageData.limit > 0) ? courses.slice(0, pageData.limit) : courses;\n }\n\n // Finished setting up the current page\n loadedPages[currentPage] = {\n courses: pageCourses\n };\n\n // Set up the next page (if there is more than one page).\n var remainingCourses = nextPageStart !== false ? courses.slice(nextPageStart, courses.length) : [];\n if (remainingCourses.length) {\n loadedPages[currentPage + 1] = {\n courses: remainingCourses\n };\n }\n\n // Set the last page to either the current or next page\n if (loadedPages[currentPage].courses.length < pageData.limit || !remainingCourses.length) {\n lastPage = currentPage;\n actions.allItemsLoaded(currentPage);\n } else if (loadedPages[currentPage + 1] != undefined\n && loadedPages[currentPage + 1].courses.length < pageData.limit) {\n lastPage = currentPage + 1;\n }\n\n courseOffset = coursesData.nextoffset;\n return renderCourses(root, loadedPages[currentPage]);\n })\n .catch(Notification.exception);\n\n promises.push(pagePromise);\n });\n\n return promises;\n },\n config\n );\n\n pagedContentPromise.then(function(html, js) {\n registerPagedEventHandlers(root, namespace);\n return Templates.replaceNodeContents(root.find(Selectors.courseView.region), html, js);\n }).catch(Notification.exception);\n };\n\n /**\n * Listen to, and handle events for the myoverview block.\n *\n * @param {Object} root The myoverview block container element.\n */\n var registerEventListeners = function(root) {\n CustomEvents.define(root, [\n CustomEvents.events.activate\n ]);\n\n root.on(CustomEvents.events.activate, SELECTORS.ACTION_ADD_FAVOURITE, function(e, data) {\n var favourite = $(e.target).closest(SELECTORS.ACTION_ADD_FAVOURITE);\n var courseId = getCourseId(favourite);\n addToFavourites(root, courseId);\n data.originalEvent.preventDefault();\n });\n\n root.on(CustomEvents.events.activate, SELECTORS.ACTION_REMOVE_FAVOURITE, function(e, data) {\n var favourite = $(e.target).closest(SELECTORS.ACTION_REMOVE_FAVOURITE);\n var courseId = getCourseId(favourite);\n removeFromFavourites(root, courseId);\n data.originalEvent.preventDefault();\n });\n\n root.on(CustomEvents.events.activate, SELECTORS.FAVOURITE_ICON, function(e, data) {\n data.originalEvent.preventDefault();\n });\n\n root.on(CustomEvents.events.activate, SELECTORS.ACTION_HIDE_COURSE, function(e, data) {\n var target = $(e.target).closest(SELECTORS.ACTION_HIDE_COURSE);\n var courseId = getCourseId(target);\n hideCourse(root, courseId);\n data.originalEvent.preventDefault();\n });\n\n root.on(CustomEvents.events.activate, SELECTORS.ACTION_SHOW_COURSE, function(e, data) {\n var target = $(e.target).closest(SELECTORS.ACTION_SHOW_COURSE);\n var courseId = getCourseId(target);\n showCourse(root, courseId);\n data.originalEvent.preventDefault();\n });\n };\n\n /**\n * Intialise the courses list and cards views on page load.\n *\n * @param {object} root The root element for the courses view.\n */\n var init = function(root) {\n root = $(root);\n loadedPages = [];\n lastPage = 0;\n courseOffset = 0;\n\n initializePagedContent(root);\n\n if (!root.attr('data-init')) {\n registerEventListeners(root);\n root.attr('data-init', true);\n }\n };\n\n /**\n * Reset the courses views to their original\n *\n * state on first page load.courseOffset\n *\n * This is called when configuration has changed for the event lists\n * to cause them to reload their data.\n *\n * @param {Object} root The root element for the timeline view.\n */\n var reset = function(root) {\n if (loadedPages.length > 0) {\n loadedPages.forEach(function(courseList, index) {\n var pagedContentPage = getPagedContentContainer(root, index);\n renderCourses(root, courseList).then(function(html, js) {\n return Templates.replaceNodeContents(pagedContentPage, html, js);\n }).catch(Notification.exception);\n });\n } else {\n init(root);\n }\n };\n\n return {\n init: init,\n reset: reset\n };\n});\n"],"names":["define","$","Repository","PagedContentFactory","PubSub","CustomEvents","Notification","Templates","CourseEvents","Selectors","PagedContentEvents","Aria","SELECTORS","TEMPLATES","GROUPINGS","NUMCOURSES_PERPAGE","loadedPages","courseOffset","lastPage","lastLimit","namespace","getFilterValues","root","courseRegion","find","courseView","region","display","attr","grouping","sort","displaycategories","customfieldname","customfieldvalue","DEFAULT_PAGED_CONTENT_CONFIG","ignoreControlWhileLoading","controlPlacementBottom","persistentLimitKey","getFavouriteIconContainer","courseId","getPagedContentContainer","index","getCourseId","getAddFavouriteMenuItem","getRemoveFavouriteMenuItem","addToFavourites","removeAction","addAction","setCourseFavouriteState","then","success","publish","favourited","removeClass","addClass","iconContainer","isFavouriteIcon","unhide","notFavourteIcon","hide","showFavouriteIcon","alert","catch","exception","removeFromFavourites","unfavorited","hideFavouriteIcon","getHideCourseMenuItem","getShowCourseMenuItem","setCourseHiddenState","status","updateUserPreferences","preferences","type","value","hideElement","id","pagingBar","jumpto","parseInt","reducedCourse","courses","reduce","accumulator","current","push","undefined","newElement","slice","forEach","courseList","popElement","merge","length","pagedContentContainer","resetLastPageNumber","pagedContentPage","renderCourses","html","js","replaceNodeContents","remove","setFavouriteCourses","result","warnings","course","isfavourite","coursesData","filters","currentTemplate","map","showcoursecategory","render","nocoursesimg","setLimit","limit","registerPagedEventHandlers","event","SET_ITEMS_PER_PAGE_LIMIT","subscribe","bind","initializePagedContent","Math","random","pagingLimit","itemsPerPage","active","totalCourseCount","filter","pagingOption","config","extend","eventNamespace","pagedContentPromise","createWithLimit","pagesData","actions","promises","pageData","currentPage","pageNumber","allItemsLoaded","pagePromise","getEnrolledCoursesByTimeline","offset","classification","getMyCourses","nextPageStart","pageCourses","currentPageLength","remainingCourses","nextoffset","registerEventListeners","events","activate","on","e","data","favourite","target","closest","originalEvent","preventDefault","hideAction","showAction","hideCourse","showCourse","init","reset"],"mappings":"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"}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists