<commit_before>package installers;


import haxe.Int32;
import haxe.io.Bytes;
import haxe.SHA1;
import neko.FileSystem;
import neko.io.File;
import neko.io.Path;
import neko.Lib;
import neko.Sys;
import data.Asset;
import neko.zip.Writer;
import nme.utils.ByteArray;

import format.swf.Data;
import format.swf.Constants;
import format.mp3.Data;
import format.wav.Data;

import nme.text.Font;


class FlashInstaller extends InstallerBase {
	
	
	override function build ():Void {
		
		var destination:String = buildDirectory + "/flash/bin";
		var hxml:String = buildDirectory + "/flash/haxe/" + (debug ? "debug" : "release") + ".hxml";
		
		runCommand ("", "haxe", [ hxml ] );
		
		var file = defines.get ("APP_FILE") + ".swf";
		var input = neko.io.File.read (destination + "/" + file, true);
		var reader = new format.swf.Reader (input);
		var swf = reader.read ();
		input.close();
		
		var new_tags = new Array <SWFTag> ();
		var inserted = false;
		
		for (tag in swf.tags) {
			
			var name = Type.enumConstructor(tag);
			//trace(name);
			//if (name=="TSymbolClass") trace(tag);
			
			if (name == "TShowFrame" && !inserted && assets.length > 0) {
				
				new_tags.push (TShowFrame);
				
				for (asset in assets) {
					
					if (asset.type != Asset.TYPE_TEMPLATE && toSwf (asset, new_tags)) {
						
						inserted = true;
						
					}
					
				}
				
			}
			
			new_tags.push (tag);
			
		}

		if (inserted) {
			
			swf.tags = new_tags;
			var output = neko.io.File.write (destination + "/" + file, true);
			var writer = new format.swf.Writer (output);
			writer.write (swf);
			output.close ();
			
		}
		
		if (targetFlags.exists ("web")) {
			
			recursiveCopy (NME + "/tools/command-line/flash/templates/web", buildDirectory + "/flash/bin");
			
		} else if (targetFlags.exists ("chrome")) {
			
			recursiveCopy (NME + "/tools/command-line/flash/templates/chrome", buildDirectory + "/flash/bin");
			
			getIcon (16, buildDirectory + "/flash/bin/icon_16.png");
			getIcon (128, buildDirectory + "/flash/bin/icon_128.png");
			
			//compressToZip (buildDirectory + "/flash/bin/" + defines.get ("APP_FILE") + ".crx");
			
		} else if (targetFlags.exists ("opera")) {
			
			recursiveCopy (NME + "/tools/command-line/flash/templates/opera", buildDirectory + "/flash/bin");
			
			getIcon (16, buildDirectory + "/flash/bin/icon_16.png");
			getIcon (32, buildDirectory + "/flash/bin/icon_32.png");
			getIcon (64, buildDirectory + "/flash/bin/icon_64.png");
			getIcon (128, buildDirectory + "/flash/bin/icon_128.png");
			
			compressToZip (buildDirectory + "/flash/bin/" + defines.get ("APP_FILE") + ".wgt");
			
		}
		
	}
	
	
	private function compressToZip (path:String):Void {
		
		var files = new Array <Dynamic> ();
		
		var directory = Path.directory (path);
		
		for (file in FileSystem.readDirectory (directory)) {
			
			if (Path.extension (file) != "zip" && Path.extension (file) != "crx" && Path.extension (file) != "wgt") {
				
				var name = file;
				//var date = FileSystem.stat (directory + "/" + file).ctime;
				var date = Date.now ();
				
				var input = File.read (directory + "/" + file, true);
				var data = input.readAll ();
				input.close ();
				
				files.push ( { fileName: name, fileTime: date, data: data } );
				
			}
			
		}
		
		var output = File.write (path, true);
		
		if (Path.extension (path) == "crx") {
			
			var input = File.read (defines.get ("KEY_STORE"), true);
			var publicKey:Bytes = input.readAll ();
			input.close ();
			
			var signature = SHA1.encode ("this isn't working");
			
			output.writeString ("Cr24"); // magic number
			output.writeInt32 (Int32.ofInt (2)); // CRX file format version
			output.writeInt32 (Int32.ofInt (publicKey.length)); // public key length
			output.writeInt32 (Int32.ofInt (signature.length)); // signature length
			output.writeBytes (publicKey, 0, publicKey.length);
			output.writeString (signature);
			
			//output.writeBytes (); // public key contents "The contents of the author's RSA public key, formatted as an X509 SubjectPublicKeyInfo block. "
			//output.writeBytes (); // "The signature of the ZIP content using the author's private key. The signature is created using the RSA algorithm with the SHA-1 hash function."
			
		}
		
		Writer.writeZip (output, files, 1);
		output.close ();
		
	}
	
	
	static var swfAssetID = 1000;
	
	function nextAssetID () {
		
		return swfAssetID++;
		
	}
   

	public function toSwf (inAsset:Asset, outTags:Array<SWFTag>) {
		
		var embed = inAsset.embed;
		var name = inAsset.sourcePath;
		var type = inAsset.type;
		var flatName = inAsset.flatName;
		
		if (!embed) {
			
			return false;
			
		}
		
		var cid = nextAssetID ();
		
		if (type == "music" || type == "sound") {
			
			var src = name;
			var ext = neko.io.Path.extension (src);
			
			if (ext != "mp3" && ext != "wav") {
				
				for (e in ["wav", "mp3"]) {
					
					src = name.substr (0, name.length - ext.length) + e;
					
					if (neko.FileSystem.exists (src)) {
						
						break;
						
					}
					
				}
				
			}
			
			if (!neko.FileSystem.exists (src)) {
				
				throw "Could not find mp3/wav source: " + src;
				
			}
			
			var ext = neko.io.Path.extension (src);
			
			var input = neko.io.File.read (src, true);
			
			if (ext == "mp3") {
				
				// Code lifted from "samhaxe"
				var r = new format.mp3.Reader (input);
				var mp3 = r.read ();
				
				if (mp3.frames.length == 0) {
					
					throw "No frames found in mp3: " + src;
					
				}
				
				// Guess about the format based on the header of the first frame found
				var fr0 = mp3.frames[0];
				var hdr0 = fr0.header;
				
				// Verify Layer3-ness
				if (hdr0.layer != Layer.Layer3) {
					
					throw "Only Layer-III mp3 files are supported by flash. File " + src + " is: " + format.mp3.Tools.getFrameInfo (fr0);
					
				}
<commit_msg>Throw warnings when OGG files cannot be embedded in Flash, instead of halting the build process<commit_after>package installers;


import haxe.Int32;
import haxe.io.Bytes;
import haxe.SHA1;
import neko.FileSystem;
import neko.io.File;
import neko.io.Path;
import neko.Lib;
import neko.Sys;
import data.Asset;
import neko.zip.Writer;
import nme.utils.ByteArray;

import format.swf.Data;
import format.swf.Constants;
import format.mp3.Data;
import format.wav.Data;

import nme.text.Font;


class FlashInstaller extends InstallerBase {
	
	
	override function build ():Void {
		
		var destination:String = buildDirectory + "/flash/bin";
		var hxml:String = buildDirectory + "/flash/haxe/" + (debug ? "debug" : "release") + ".hxml";
		
		runCommand ("", "haxe", [ hxml ] );
		
		var file = defines.get ("APP_FILE") + ".swf";
		var input = neko.io.File.read (destination + "/" + file, true);
		var reader = new format.swf.Reader (input);
		var swf = reader.read ();
		input.close();
		
		var new_tags = new Array <SWFTag> ();
		var inserted = false;
		
		for (tag in swf.tags) {
			
			var name = Type.enumConstructor(tag);
			//trace(name);
			//if (name=="TSymbolClass") trace(tag);
			
			if (name == "TShowFrame" && !inserted && assets.length > 0) {
				
				new_tags.push (TShowFrame);
				
				for (asset in assets) {
					
					if (asset.type != Asset.TYPE_TEMPLATE && toSwf (asset, new_tags)) {
						
						inserted = true;
						
					}
					
				}
				
			}
			
			new_tags.push (tag);
			
		}

		if (inserted) {
			
			swf.tags = new_tags;
			var output = neko.io.File.write (destination + "/" + file, true);
			var writer = new format.swf.Writer (output);
			writer.write (swf);
			output.close ();
			
		}
		
		if (targetFlags.exists ("web")) {
			
			recursiveCopy (NME + "/tools/command-line/flash/templates/web", buildDirectory + "/flash/bin");
			
		} else if (targetFlags.exists ("chrome")) {
			
			recursiveCopy (NME + "/tools/command-line/flash/templates/chrome", buildDirectory + "/flash/bin");
			
			getIcon (16, buildDirectory + "/flash/bin/icon_16.png");
			getIcon (128, buildDirectory + "/flash/bin/icon_128.png");
			
			//compressToZip (buildDirectory + "/flash/bin/" + defines.get ("APP_FILE") + ".crx");
			
		} else if (targetFlags.exists ("opera")) {
			
			recursiveCopy (NME + "/tools/command-line/flash/templates/opera", buildDirectory + "/flash/bin");
			
			getIcon (16, buildDirectory + "/flash/bin/icon_16.png");
			getIcon (32, buildDirectory + "/flash/bin/icon_32.png");
			getIcon (64, buildDirectory + "/flash/bin/icon_64.png");
			getIcon (128, buildDirectory + "/flash/bin/icon_128.png");
			
			compressToZip (buildDirectory + "/flash/bin/" + defines.get ("APP_FILE") + ".wgt");
			
		}
		
	}
	
	
	private function compressToZip (path:String):Void {
		
		var files = new Array <Dynamic> ();
		
		var directory = Path.directory (path);
		
		for (file in FileSystem.readDirectory (directory)) {
			
			if (Path.extension (file) != "zip" && Path.extension (file) != "crx" && Path.extension (file) != "wgt") {
				
				var name = file;
				//var date = FileSystem.stat (directory + "/" + file).ctime;
				var date = Date.now ();
				
				var input = File.read (directory + "/" + file, true);
				var data = input.readAll ();
				input.close ();
				
				files.push ( { fileName: name, fileTime: date, data: data } );
				
			}
			
		}
		
		var output = File.write (path, true);
		
		if (Path.extension (path) == "crx") {
			
			var input = File.read (defines.get ("KEY_STORE"), true);
			var publicKey:Bytes = input.readAll ();
			input.close ();
			
			var signature = SHA1.encode ("this isn't working");
			
			output.writeString ("Cr24"); // magic number
			output.writeInt32 (Int32.ofInt (2)); // CRX file format version
			output.writeInt32 (Int32.ofInt (publicKey.length)); // public key length
			output.writeInt32 (Int32.ofInt (signature.length)); // signature length
			output.writeBytes (publicKey, 0, publicKey.length);
			output.writeString (signature);
			
			//output.writeBytes (); // public key contents "The contents of the author's RSA public key, formatted as an X509 SubjectPublicKeyInfo block. "
			//output.writeBytes (); // "The signature of the ZIP content using the author's private key. The signature is created using the RSA algorithm with the SHA-1 hash function."
			
		}
		
		Writer.writeZip (output, files, 1);
		output.close ();
		
	}
	
	
	static var swfAssetID = 1000;
	
	function nextAssetID () {
		
		return swfAssetID++;
		
	}
   

	public function toSwf (inAsset:Asset, outTags:Array<SWFTag>) {
		
		var embed = inAsset.embed;
		var name = inAsset.sourcePath;
		var type = inAsset.type;
		var flatName = inAsset.flatName;
		
		if (!embed) {
			
			return false;
			
		}
		
		var cid = nextAssetID ();
		
		if (type == "music" || type == "sound") {
			
			var src = name;
			var ext = neko.io.Path.extension (src);
			
			if (ext != "mp3" && ext != "wav") {
				
				for (e in ["wav", "mp3"]) {
					
					src = name.substr (0, name.length - ext.length) + e;
					
					if (neko.FileSystem.exists (src)) {
						
						break;
						
					}
					
				}
				
			}
			
			if (!neko.FileSystem.exists (src)) {
				
				Lib.println ("Warning: Could not embed unsupported audio file \"" + name + "\"");
				return false;
				
			}
			
			var ext = neko.io.Path.extension (src);
			
			var input = neko.io.File.read (src, true);
			
			if (ext == "mp3") {
				
				// Code lifted from "samhaxe"
				var r = new format.mp3.Reader (input);
				var mp3 = r.read ();
				
				if (mp3.frames.length == 0) {
					
					throw "No frames found in mp3: " + src;
					
				}
				
				// Guess about the format based on the header of the first frame found
				var fr0 = mp3.frames[0];
				var hdr0 = fr0.header;
				
				// Verify Layer3-ness
				if (hdr0.layer != Layer.Layer3) {
					
					throw "Only Layer-III mp3 files are supported by flash. File " + src + " is: " + format.mp3.Tools.getFrameInfo (fr0);
					
				}

{'fraction_non_alphanumeric': 0.14827032056161718, 'fraction_numerical': 0.013448363359553413, 'mean_word_length': 2.565741857659831, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 23, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5320038', 'n_tokens_mistral': 5040, 'n_tokens_neox': 3869, 'n_words': 1022}