### Example JSON Module Link Source: https://soradocs.readthedocs.io/en/latest/files/how_to_test An example of a raw file link for a JSON module hosted on GitHub, which is used to configure Sora modules. ```text https://raw.githubusercontent.com/50n50/maisgay/refs/heads/main/hianime/hianime.json ``` -------------------------------- ### Example Tail Command Usage Source: https://soradocs.readthedocs.io/en/latest/files/how_to_test An example demonstrating the usage of the `tail -f` command to monitor a specific log file within the Sora application's document directory on macOS. ```bash tail -f /Users/paul/Library/Containers/me.cranci.sulfur/Data/Documents/logs.txt ``` -------------------------------- ### Sora Module File Hosting Example Source: https://soradocs.readthedocs.io/en/latest/_sources/files/how_to_test.md This example demonstrates the expected format for raw file links when hosting JavaScript and JSON files for Sora modules. It highlights the use of GitHubusercontent for direct file access. ```text https://raw.githubusercontent.com/50n50/maisgay/refs/heads/main/hianime/hianime.json ``` -------------------------------- ### JavaScript Example: Using unpack function Source: https://soradocs.readthedocs.io/en/latest/_sources/files/deobfuscator.md Demonstrates how to use the `unpack` deobfuscator function within a practical scenario. It shows how to extract obfuscated script content from HTML and then pass it to the `unpack` function to get the deobfuscated code. ```javascript //Example usage function placeholder(html) { const obfuscatedScript = html.match(/]*>\s*(eval\(function\(p,a,c,k,e,d.*?\)[\s\S]*?)\s*<\/script>/); const unpackedScript = unpack(obfuscatedScript[1]); console.log(unpackedScript); return unpackedScript; } ``` -------------------------------- ### Sora JSON Example - Hianime Source: https://soradocs.readthedocs.io/en/latest/files/mainjson A practical JSON configuration example for the 'Hianime' streaming source, demonstrating how to populate the fields for a specific module. ```JSON { "sourceName": "Hianime", "iconUrl": "https://raw.githubusercontent.com/50n50/maisgay/refs/heads/main/hianime/icon.png", "author": { "name": "50/50", "icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:&s" }, "version": "1.0.1", "language": "English (DUB)", "streamType": "HLS", "quality": "720p", "baseUrl": "https://api.animemundo.net/", "searchBaseUrl": "https://api.animemundo.net/api/v2/hianime/search?q=%s", "scriptUrl": "https://raw.githubusercontent.com/50n50/maisgay/refs/heads/main/hianime/hianime.js", "asyncJS": true } ``` -------------------------------- ### Fetch URL v2 (GET Request) - JavaScript Source: https://soradocs.readthedocs.io/en/latest/files/javascriptmethods An improved function for fetching URLs, returning a Promise with an enhanced response object that includes .text() and .json() methods for easier parsing. Supports GET, POST, PUT, and PATCH methods. This example demonstrates a GET request. ```javascript const url = "http://example.org"; const headers = { // Optional 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', 'Content-Type': 'application/json', 'Referer': 'http://example.org' } const response = await fetchv2(url, headers); const data = await response.json(); // or response.text(); ``` -------------------------------- ### Sora JSON Full Format Example Source: https://soradocs.readthedocs.io/en/latest/files/mainjson A comprehensive example illustrating the complete JSON structure required for configuring a Sora streaming module, including all defined fields and their typical values. ```JSON { "sourceName": "YourSourceName", "iconUrl": "https://your-source.com/icon.png", "author": { "name": "AuthorName", "icon": "https://your-source.com/author-icon.png" }, "version": "1.0.0", "language": "English (DUB)", "streamType": "HLS", "quality": "720p", "baseUrl": "https://api.your-source.com/", "searchBaseUrl": "https://your-source.com/search=%s", "scriptUrl": "https://your-source.com/script.js", "asyncJS": true, "streamAsyncJS": false, "softsub": true } ``` -------------------------------- ### JavaScript unpack function input example Source: https://soradocs.readthedocs.io/en/latest/files/deobfuscator Shows an example of obfuscated code that can be processed by the `unpack` function. This input format is typical for JavaScript obfuscation. ```javascript eval(function(p,a,c,k,e,d){while(c--)if(k[c])p=p ... ``` -------------------------------- ### POST Request Example with fetchv2 Source: https://soradocs.readthedocs.io/en/latest/files/javascriptmethods Demonstrates making a POST request using a hypothetical `fetchv2` function. It shows how to set URL, headers, method, and body, and process the response. Dependencies include the `fetchv2` function and standard JavaScript fetch API for response handling. ```javascript const url = "http://example.org"; const headers = { // Optional 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', 'Content-Type': 'application/json', 'Referer': 'http://example.org' } const method = "POST"; const body = { key: "value", key2: "value2" } const response = await fetchv2(url, headers, method, body); const data = await response.json(); // or response.text(); ``` -------------------------------- ### JavaScript unpack function usage example Source: https://soradocs.readthedocs.io/en/latest/files/deobfuscator Demonstrates how to use the `unpack` function to deobfuscate a script. It takes an obfuscated script as input and returns the deobfuscated version. ```javascript const unpackedScript = unpack(obfuscatedScript[1]); ``` -------------------------------- ### JavaScript Deobfuscator Example and Implementation Source: https://soradocs.readthedocs.io/en/latest/files/deobfuscator This snippet demonstrates how to use a JavaScript deobfuscator to unpack obfuscated scripts. It includes the core 'Unbaser' class, 'detect', and 'unpack' functions, along with helper functions for argument filtering and string replacement. The code is designed to handle Packer-generated obfuscation. ```javascript //Example usage function placeholder(html) { const obfuscatedScript = html.match(/]*>\s*(eval\(function\(p,a,c,k,e,d.*?\)[\s\S]*?get\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ ``` -------------------------------- ### Extract Anime Details from URL Source: https://soradocs.readthedocs.io/en/latest/files/softsubjsmode Retrieves detailed information about an anime from the Hianime API using its ID extracted from a URL. It parses the response to get the description, duration, and airdate. Includes error handling for API calls. ```javascript async function extractDetails(url) { try { const match = url.match(/https://hianime\.to\/watch\/(.+)$/); const encodedID = match[1]; const response = await fetch(`https://api.animemundo.net/api/v2/hianime/anime/${encodedID}`); const data = JSON.parse(response); const animeInfo = data.data.anime.info; const moreInfo = data.data.anime.moreInfo; const transformedResults = [{ description: animeInfo.description || 'No description available', aliases: `Duration: ${animeInfo.stats?.duration || 'Unknown'}`, airdate: `Aired: ${moreInfo?.aired || 'Unknown'}` }]; return JSON.stringify(transformedResults); } catch (error) { console.log('Details error:', error); return JSON.stringify([{ description: 'Error loading description', aliases: 'Duration: Unknown', airdate: 'Aired: Unknown' }]); } } ``` -------------------------------- ### JavaScript unpack function output example Source: https://soradocs.readthedocs.io/en/latest/files/deobfuscator Illustrates the expected deobfuscated code output after processing with the `unpack` function. This output is typically a functional JavaScript code block. ```javascript jwplayer("vplayer").setup({ debug: "1", sources: [{ file: "[STREAM LINK]" }], ... }); ``` -------------------------------- ### Fetch URL with Enhanced Response - JavaScript Source: https://soradocs.readthedocs.io/en/latest/_sources/files/javascriptmethods.md An improved fetch method returning a Promise with an enhanced response object, including .text() and .json() methods for easier parsing. Supports GET, POST, PUT, and PATCH methods. ```javascript const url = "http://example.org"; const headers = { // Optional 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', 'Content-Type': 'application/json', 'Referer': 'http://example.org' } const response = await fetchv2(url, headers); const data = await response.json(); // or response.text(); ``` ```javascript const url = "http://example.org"; const headers = { // Optional 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', 'Content-Type': 'application/json', 'Referer': 'http://example.org' } const method = "POST"; const body = { key: "value", key2: "value2" } const response = await fetchv2(url, headers, method, body); const data = await response.json(); // or response.text(); ``` -------------------------------- ### JavaScript Deobfuscator: detect function Source: https://soradocs.readthedocs.io/en/latest/_sources/files/deobfuscator.md A utility function to detect if a given source string appears to be packed using a specific obfuscation pattern. It checks if the string starts with the characteristic "eval(function(p,a,c,k,e," sequence after removing whitespace. ```javascript function detect(source) { return source.replace(" ", "").startsWith("eval(function(p,a,c,k,e,"); } ``` -------------------------------- ### Extract Stream URL and Subtitles Source: https://soradocs.readthedocs.io/en/latest/files/softsubjsmode Gets the HLS stream URL and English subtitle track file for a given anime episode URL from the Hianime API. It finds the appropriate source and track from the API response. Returns null if sources are not found or an error occurs. ```javascript async function extractStreamUrl(url) { try { const match = url.match(/https://hianime\.to\/watch\/(.+)$/); const encodedID = match[1]; const response = await fetch(`https://api.animemundo.net/api/v2/hianime/episode/sources?animeEpisodeId=${encodedID}&category=sub`); const data = JSON.parse(response); const hlsSource = data.data.sources.find(source => source.type === 'hls'); const subtitleTrack = data.data.tracks.find(track => track.label === 'English' && track.kind === 'captions'); const result = { stream: hlsSource ? hlsSource.url : null, subtitles: subtitleTrack ? subtitleTrack.file : null }; console.log(result); return JSON.stringify(result); } catch (error) { console.log('Fetch error:', error); return JSON.stringify({ stream: null, subtitles: null }); } } ``` -------------------------------- ### Tail Command for Live Logs Source: https://soradocs.readthedocs.io/en/latest/files/how_to_test A bash command to monitor log files in real-time. This is useful for debugging Sora modules on macOS by observing live output. ```bash tail -f [PATH TO LOG.TXT FILE IN THE SULFUR DOCUMENTS FOLDER] ``` -------------------------------- ### Live Logging with Tail Command Source: https://soradocs.readthedocs.io/en/latest/_sources/files/how_to_test.md This snippet shows how to monitor log files in real-time using the `tail -f` command in a macOS terminal. It requires the specific path to the log file within the Sora application's documents directory. ```bash tail -f [PATH TO LOG.TXT FILE IN THE SULFUR DOCUMENTS FOLDER] ``` ```bash tail -f /Users/paul/Library/Containers/me.cranci.sulfur/Data/Documents/logs.txt ``` -------------------------------- ### Sora JSON Configuration Fields Source: https://soradocs.readthedocs.io/en/latest/files/mainjson Defines the structure and properties for Sora's main JSON configuration file. Each field specifies the data type, whether it's required, and provides a description of its purpose in managing streaming modules. ```APIDOC Sora JSON Configuration Fields: - sourceName: string - Description: Name of the source. - Required: Yes - author: object - Description: Information about the module’s author. - Required: Yes - Properties: - name: string - Description: Name of the author. - Required: Yes - icon: string - Description: Icon of the author. - Required: Yes - iconUrl: string - Description: URL to the module’s icon. - Required: Yes - version: integer - Description: Version of the module. - Required: Yes - language: string - Description: Language of the module. - Required: Yes - baseUrl: string - Description: Base URL of the source. - Required: Yes - streamType: string - Description: Stream type of the module. - Required: Yes - Allowed Values: `HLS`, `MP4` - quality: string - Description: Quality of the stream. - Required: Yes - Allowed Values: `360p`, `720p`, `1080p` - searchBaseUrl: string - Description: Search URL of the source. Must include `%s` where the search query will go. - Required: Yes - Variables: `%s` - scriptUrl: string - Description: URL to the raw link of the JavaScript file. - Required: Yes - asyncJS: boolean - Description: Set to `true` to load the script asynchronously. - Required: No - Allowed Values: `true`, `false` - streamAsyncJS: boolean - Description: Set to `true` to only load the stream function asynchronously. - Required: No - Allowed Values: `true`, `false` - softsub: boolean - Description: Set to `true` to load subtitles. - Required: No - Allowed Values: `true`, `false` - type: string - Description: Category of what the site provides. Required for the module library. - Required: No - Allowed Values: `anime`, `movies`, `shows` ``` -------------------------------- ### Sora JSON Module Configuration Structure Source: https://soradocs.readthedocs.io/en/latest/_sources/files/mainjson.md Defines the structure and fields required for Sora's JSON configuration files, which are used to manage and integrate streaming modules. This includes details on source name, author information, streaming settings, and script URLs. ```json { "sourceName": "YourSourceName", "iconUrl": "https://your-source.com/icon.png", "author": { "name": "AuthorName", "icon": "https://your-source.com/author-icon.png" }, "version": "1.0.0", "language": "English (DUB)", "streamType": "HLS", "quality": "720p", "baseUrl": "https://api.your-source.com/", "searchBaseUrl": "https://your-source.com/search=%s", "scriptUrl": "https://your-source.com/script.js", "asyncJS": true, "streamAsyncJS": false, "softsub": true } ``` ```json { "sourceName": "Hianime", "iconUrl": "https://raw.githubusercontent.com/50n50/maisgay/refs/heads/main/hianime/icon.png", "author": { "name": "50/50", "icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:&s" }, "version": "1.0.1", "language": "English (DUB)", "streamType": "HLS", "quality": "720p", "baseUrl": "https://api.animemundo.net/", "searchBaseUrl": "https://api.animemundo.net/api/v2/hianime/search?q=%s", "scriptUrl": "https://raw.githubusercontent.com/50n50/maisgay/refs/heads/main/hianime/hianime.js", "asyncJS": true } ``` -------------------------------- ### extractDetails Function Source: https://soradocs.readthedocs.io/en/latest/files/softsubjsmode Extracts detailed information from a given URL. The function returns a JSON object containing the description, aliases, and airdate of the content. This is typically used to fetch metadata for a specific item. ```APIDOC extractDetails(url: string) - Input: HTML/URL (Depending on the mode) - Output: JSON - Description: Extracts the details from the provided URL. - Example Output: { "description": "An exciting anime series about adventures.", "aliases": "Alternate Name", "airdate": "2022" } ``` -------------------------------- ### Search Anime Results Source: https://soradocs.readthedocs.io/en/latest/_sources/files/asnycjsmode.md Fetches and filters anime search results from the animemundo.net API based on a keyword. It returns a list of anime titles, images, and URLs, specifically including only those with available dub episodes. Dependencies include the fetch API. ```javascript async function searchResults(keyword) { try { const encodedKeyword = encodeURIComponent(keyword); const responseText = await fetch(`https://api.animemundo.net/api/v2/hianime/search?q=${encodedKeyword}&language=dub`); const data = JSON.parse(responseText); const filteredAnimes = data.data.animes.filter(anime => anime.episodes.dub !== null); const transformedResults = data.data.animes.map(anime => ({ title: anime.name, image: anime.poster, href: `https://hianime.to/watch/${anime.id}` })); return JSON.stringify(transformedResults); } catch (error) { console.log('Fetch error:', error); return JSON.stringify([{ title: 'Error', image: '', href: '' }]); } } ``` -------------------------------- ### Extract Anime Episodes (JavaScript) Source: https://soradocs.readthedocs.io/en/latest/files/asnycjsmode Fetches a list of episodes for a given anime URL from the animemundo.net API. It parses the anime ID from the URL and makes an API request to get episode data. The function then transforms this data into a list of objects, each containing the episode number and a direct watch link. Error handling is included for network or parsing issues. ```javascript async function extractEpisodes(url) { try { const match = url.match(/https://hianime\.to\/watch\/(.+)$/); const encodedID = match[1]; const response = await fetch(`https://api.animemundo.net/api/v2/hianime/anime/${encodedID}/episodes`); const data = JSON.parse(response); const transformedResults = data.data.episodes.map(episode => ({ href: `https://hianime.to/watch/${encodedID}?ep=${episode.episodeId.split('?ep=')[1]}`, number: episode.number })); return JSON.stringify(transformedResults); } catch (error) { console.log('Fetch error:', error); } } ``` -------------------------------- ### Extract Anime Details Source: https://soradocs.readthedocs.io/en/latest/_sources/files/asnycjsmode.md Retrieves detailed information for a specific anime from the animemundo.net API using its URL. It extracts the description, duration, and airdate, returning them in a structured JSON format. Requires a valid anime URL as input. ```javascript async function extractDetails(url) { try { const match = url.match(/https://hianime\.to\/watch\/(.+)$/); const encodedID = match[1]; const response = await fetch(`https://api.animemundo.net/api/v2/hianime/anime/${encodedID}`); const data = JSON.parse(response); const animeInfo = data.data.anime.info; const moreInfo = data.data.anime.moreInfo; const transformedResults = [{ description: animeInfo.description || 'No description available', aliases: `Duration: ${animeInfo.stats?.duration || 'Unknown'}`, airdate: `Aired: ${moreInfo?.aired || 'Unknown'}` }]; return JSON.stringify(transformedResults); } catch (error) { console.log('Details error:', error); return JSON.stringify([{ description: 'Error loading description', aliases: 'Duration: Unknown', airdate: 'Aired: Unknown' }]); } } ``` -------------------------------- ### Extract Stream URL from HTML using JavaScript Source: https://soradocs.readthedocs.io/en/latest/files/streamasyncjsmode This asynchronous JavaScript function extracts an embed URL from an HTML string, then fetches content from that URL to find a direct video stream URL. It looks for a 'data-source' attribute to get the embed URL and then uses 'fetch' to retrieve the content from the embed URL, finally extracting an MP4 stream URL using a regular expression. The function returns the video URL or 'null' if an error occurs or the URL is not found. ```javascript async function extractStreamUrl(html) { try { const sourceMatch = html.match(/data-source="([^"]+)"/); const embedUrl = sourceMatch?.[1]?.replace(/&/g, '&'); if (!embedUrl) return null; const response = await fetch(embedUrl); const data = await response; const videoUrl = data.match(/src:\s*'(https:\/\/[^']+\.mp4[^']*)'/)?.[1]; console.log(videoUrl); return videoUrl || null; } catch (error) { return null; } } ``` -------------------------------- ### Fetch URL (Deprecated) - JavaScript Source: https://soradocs.readthedocs.io/en/latest/_sources/files/javascriptmethods.md Fetches a URL, returning the raw response. This method is deprecated and does not support .json() or .text() methods directly. Users should parse the response manually or use fetchv2. ```javascript const url = "http://example.org"; const headers = { // Optional 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', 'Content-Type': 'application/json', 'Referer': 'http://example.org' } const response = await fetch(url, headers); const data = await JSON.parse(response); ``` -------------------------------- ### btoa: Encode String to Base64 Source: https://soradocs.readthedocs.io/en/latest/files/javascriptmethods Encodes a given binary string into a Base64-encoded ASCII string. This is commonly used for encoding data before transmission or storage. Returns null if the input is not a valid Base64 string. ```javascript const encoded = btoa("Hello, world!"); console.log(encoded); // Outputs: "SGVsbG8sIHdvcmxkIQ==" ``` -------------------------------- ### Search Anime Results using API Source: https://soradocs.readthedocs.io/en/latest/files/softsubjsmode Fetches anime search results from the Hianime API based on a keyword. It parses the JSON response and transforms it into a list of anime titles, images, and links. Handles potential fetch errors. ```javascript async function searchResults(keyword) { try { const encodedKeyword = encodeURIComponent(keyword); const responseText = await fetch(`https://api.animemundo.net/api/v2/hianime/search?q=${encodedKeyword}&language=sub`); const data = JSON.parse(responseText); const transformedResults = data.data.animes.map(anime => ({ title: anime.name, image: anime.poster, href: `https://hianime.to/watch/${anime.id}` })); return JSON.stringify(transformedResults); } catch (error) { console.log('Fetch error:', error); return JSON.stringify([{ title: 'Error', image: '', href: '' }]); } } ``` -------------------------------- ### macOS Sora Module Cache Path Source: https://soradocs.readthedocs.io/en/latest/files/how_to_test The default file path on macOS where Sora application caches modules. This path may vary if a custom Bundle Identifier was used during Xcode builds. ```text /Users/[Your username]/Library/Containers/me.cranci.sulfur/Data/Documents/ ``` -------------------------------- ### Fetch URL (Deprecated) - JavaScript Source: https://soradocs.readthedocs.io/en/latest/files/javascriptmethods Fetches a URL and returns its content as a String. This method is deprecated and should not be used for JSON or text parsing directly; use JSON.parse() or direct assignment instead. It is recommended to use fetchv2. ```javascript const url = "http://example.org"; const headers = { // Optional 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', 'Content-Type': 'application/json', 'Referer': 'http://example.org' } const response = await fetch(url, headers); const data = await JSON.parse(response); ``` -------------------------------- ### Implement JavaScript functions for HTML parsing and data extraction Source: https://soradocs.readthedocs.io/en/latest/_sources/files/streamasyncjsmode.md Provides JavaScript implementations for `searchResults`, `extractDetails`, `extractEpisodes`, and `extractStreamUrl` functions. These functions parse HTML content using regular expressions to extract specific data points like titles, links, images, descriptions, and episode details, or asynchronously fetch and extract stream URLs. ```javascript function searchResults(html) { const results = []; const titleRegex = /]*>(.*?)<\/h2>/; const hrefRegex = /]*>/; const imgRegex = /]*src="([^"]+)"[^>]*>/; const itemRegex = /
]*>[\s\S]*?<\/div>\s*<\/div>\s*<\/div>/g; const items = html.match(itemRegex) || []; items.forEach((itemHtml) => { const titleMatch = itemHtml.match(titleRegex); const title = titleMatch ? titleMatch[1].trim() : ''; const hrefMatch = itemHtml.match(hrefRegex); const href = hrefMatch ? hrefMatch[1].trim() : ''; const imgMatch = itemHtml.match(imgRegex); const imageUrl = imgMatch ? imgMatch[1].trim() : ''; if (title && href) { results.push({ title: title, image: imageUrl, href: href }); } }); return results; } function extractDetails(html) { const details = []; const descriptionMatch = html.match(/

([\s\S]*?)<\/p>/); let description = descriptionMatch ? descriptionMatch[1].trim() : ''; const airdateMatch = html.match(/]*title="([^"]+)">[^<]+<\/td>/); let airdate = airdateMatch ? airdateMatch[1].trim() : ''; if (description && airdate) { details.push({ description: description, aliases: 'N/A', airdate: airdate }); } console.log(details); return details; } function extractEpisodes(html) { const episodes = []; const htmlRegex = /]*href="([^"]*?\/episode\/[^"]*?)"[^>]*>[\s\S]*?الحلقة\s+(\d+)[\s\S]*?<\/a>/gi; const plainTextRegex = /الحلقة\s+(\d+)/g; let matches; if ((matches = html.match(htmlRegex))) { matches.forEach(link => { const hrefMatch = link.match(/href="([^"]+)"/); const numberMatch = link.match(/الحلقة\s+(\d+)/); if (hrefMatch && numberMatch) { const href = hrefMatch[1]; const number = numberMatch[1]; episodes.push({ href: href, number: number }); } }); } else if ((matches = html.match(plainTextRegex))) { matches.forEach(match => { const numberMatch = match.match(/\d+/); if (numberMatch) { episodes.push({ href: null, number: numberMatch[0] }); } }); } console.log(episodes); return episodes; } async function extractStreamUrl(html) { try { const sourceMatch = html.match(/data-source="([^"]+)"/); const embedUrl = sourceMatch?.[1]?.replace(/&/g, '&'); if (!embedUrl) return null; const response = await fetch(embedUrl); const data = await response; const videoUrl = data.match(/src:\s*'(https:\/\/[^']+\.mp4[^']*)'/)?.[1]; console.log(videoUrl); return videoUrl || null; } catch (error) { return null; } } ``` -------------------------------- ### Encode String to Base64 - JavaScript Source: https://soradocs.readthedocs.io/en/latest/_sources/files/javascriptmethods.md Encodes a given binary string into a Base64-encoded ASCII string. Returns null if the input is not a valid Base64 string. ```javascript const encoded = btoa("Hello, world!"); console.log(encoded); // Outputs: "SGVsbG8sIHdvcmxkIQ==" ``` -------------------------------- ### Extract Anime Details (JavaScript) Source: https://soradocs.readthedocs.io/en/latest/_sources/files/softsubjsmode.md Extracts detailed information about an anime from its URL. It parses the anime ID from the URL, fetches detailed data from the Hianime API, and structures it into a JSON object containing description, aliases, and airdate. Includes error handling for API requests. ```javascript async function extractDetails(url) { try { const match = url.match(/https://hianime\.to\/watch\/(.+)$/); const encodedID = match[1]; const response = await fetch(`https://api.animemundo.net/api/v2/hianime/anime/${encodedID}`); const data = JSON.parse(response); const animeInfo = data.data.anime.info; const moreInfo = data.data.anime.moreInfo; const transformedResults = [{ description: animeInfo.description || 'No description available', aliases: `Duration: ${animeInfo.stats?.duration || 'Unknown'}`, airdate: `Aired: ${moreInfo?.aired || 'Unknown'}` }]; return JSON.stringify(transformedResults); } catch (error) { console.log('Details error:', error); return JSON.stringify([{ description: 'Error loading description', aliases: 'Duration: Unknown', airdate: 'Aired: Unknown' }]); } } ``` ```json { "description": "An exciting anime series about adventures.", "aliases": "Alternate Name", "airdate": "2022" } ``` -------------------------------- ### Extract Anime Episodes Source: https://soradocs.readthedocs.io/en/latest/_sources/files/asnycjsmode.md Fetches a list of episodes for a given anime URL from the animemundo.net API. It returns an array of episode objects, each containing a URL and episode number. This function is dependent on the fetch API and URL parsing. ```javascript async function extractEpisodes(url) { try { const match = url.match(/https://hianime\.to\/watch\/(.+)$/); const encodedID = match[1]; const response = await fetch(`https://api.animemundo.net/api/v2/hianime/anime/${encodedID}/episodes`); const data = JSON.parse(response); const transformedResults = data.data.episodes.map(episode => ({ href: `https://hianime.to/watch/${encodedID}?ep=${episode.episodeId.split('?ep=')[1]}`, number: episode.number })); return JSON.stringify(transformedResults); } catch (error) { console.log('Fetch error:', error); } } ``` -------------------------------- ### Search Anime Results (JavaScript) Source: https://soradocs.readthedocs.io/en/latest/_sources/files/softsubjsmode.md Extracts search results from a given keyword using the Hianime API. It fetches anime data, transforms it into a structured format including title, image, and URL, and returns it as a JSON string. Handles potential fetch errors. ```javascript async function searchResults(keyword) { try { const encodedKeyword = encodeURIComponent(keyword); const responseText = await fetch(`https://api.animemundo.net/api/v2/hianime/search?q=${encodedKeyword}&language=sub`); const data = JSON.parse(responseText); const transformedResults = data.data.animes.map(anime => ({ title: anime.name, image: anime.poster, href: `https://hianime.to/watch/${anime.id}` })); return JSON.stringify(transformedResults); } catch (error) { console.log('Fetch error:', error); return JSON.stringify([{ title: 'Error', image: '', href: '' }]); } } ``` ```json { "title": "Example Title", "image": "https://example.com/image.jpg", "href": "https://grani.me/example" } ``` -------------------------------- ### Extract Details (JavaScript) Source: https://soradocs.readthedocs.io/en/latest/files/normaljsmode Extracts detailed information from HTML content. This function takes HTML as input and returns a JSON object with fields like description, aliases, and airdate. ```javascript function extractDetails(HTML) { // ... implementation details ... return { "description": "An exciting anime series about adventures.", "aliases": "Alternate Name", "airdate": "2022" }; } ``` -------------------------------- ### Extract Anime Episodes from URL Source: https://soradocs.readthedocs.io/en/latest/files/softsubjsmode Fetches a list of episodes for a specific anime from the Hianime API, using the anime ID from a URL. It transforms the episode data into a list of episode numbers and corresponding watch links. Includes basic error handling. ```javascript async function extractEpisodes(url) { try { const match = url.match(/https://hianime\.to\/watch\/(.+)$/); const encodedID = match[1]; const response = await fetch(`https://api.animemundo.net/api/v2/hianime/anime/${encodedID}/episodes`); const data = JSON.parse(response); const transformedResults = data.data.episodes.map(episode => ({ href: `https://hianime.to/watch/${encodedID}?ep=${episode.episodeId.split('?ep=')[1]}`, number: episode.number })); return JSON.stringify(transformedResults); } catch (error) { console.log('Fetch error:', error); } } ``` -------------------------------- ### extractEpisodes Function Source: https://soradocs.readthedocs.io/en/latest/files/softsubjsmode Extracts episode information from a provided URL. The function returns a JSON object containing the episode's href (link) and its number. This is essential for navigating through series content. ```APIDOC extractEpisodes(url: string) - Input: HTML/URL (Depending on the mode) - Output: JSON - Description: Extracts the episodes from the provided URL. - Example Output: { "href": "https://grani.me/episode/123", "number": "1" } ``` -------------------------------- ### atob: Decode Base64 String Source: https://soradocs.readthedocs.io/en/latest/files/javascriptmethods Decodes a Base64-encoded ASCII string back into its original binary string representation. It's useful for decoding data transmitted in Base64 format. Returns null if the input is not a valid Base64 string. ```javascript const decoded = atob("SGVsbG8sIHdvcmxkIQ=="); console.log(decoded); // Outputs: "Hello, world!" ```