Changeset 792
- Timestamp:
- 01/29/08 22:07:22 (8 months ago)
- Files:
-
- trunk/CPFPerianPrefPaneController.h (modified) (3 diffs)
- trunk/CPFPerianPrefPaneController.m (modified) (6 diffs)
- trunk/ECQTComponent.h (added)
- trunk/ECQTComponent.m (added)
- trunk/Perian.xcodeproj/project.pbxproj (modified) (4 diffs)
- trunk/PerianPrefPane.nib/classes.nib (modified) (1 diff)
- trunk/PerianPrefPane.nib/info.nib (modified) (1 diff)
- trunk/PerianPrefPane.nib/keyedobjects.nib (modified) (previous)
- trunk/Release/Read Me.rtf (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/CPFPerianPrefPaneController.h
r685 r792 84 84 NSMutableString *errorString; 85 85 86 NSArray *componentReplacementInfo;87 88 86 NSURL *perianForumURL; 89 87 NSURL *perianDonateURL; … … 111 109 112 110 //Component List 113 - (NSString *)checkComponentStatusByBundleIdentifier:(NSString *)bundleID;111 //- (NSString *)checkComponentStatusByBundleIdentifier:(NSString *)bundleID; 114 112 115 113 //About … … 119 117 120 118 @end 119 120 NSArray* GetComponentsInFolder(NSString* folder); trunk/CPFPerianPrefPaneController.m
r685 r792 1 1 #import "CPFPerianPrefPaneController.h" 2 2 #import "UpdateCheckerAppDelegate.h" 3 #import "ECQTComponent.h" 3 4 #include <sys/stat.h> 4 5 … … 228 229 else 229 230 userInstalled = YES; 230 231 #warning TODO(durin42) Should filter out components that aren't installed from this list.232 componentReplacementInfo = [[NSArray alloc] initWithContentsOfFile:[[[self bundle] resourcePath] stringByAppendingPathComponent:ComponentInfoPlist]];233 231 } 234 232 … … 362 360 363 361 /* A52 Prefs */ 364 inttwoChannelMode = [self getIntFromKey:AC3TwoChannelModeKey forAppID:a52AppID withDefault:0xffffffff];365 if (twoChannelMode != 0xffffffff)362 unsigned twoChannelMode = [self getIntFromKey:AC3TwoChannelModeKey forAppID:a52AppID withDefault:0xffffffff]; 363 if (twoChannelMode != 0xffffffff) 366 364 { 367 365 /* sanity checks */ … … 409 407 AuthorizationFree(auth, 0); 410 408 [errorString release]; 411 [componentReplacementInfo release];412 409 [super dealloc]; 413 410 } … … 698 695 } 699 696 700 #pragma mark Component Version List701 - (NSArray *)installedComponentsForUser:(BOOL)user702 {703 NSString *path = [self basePathForType:ComponentTypeQuickTime user:user];704 NSArray *installedComponents = [[NSFileManager defaultManager] directoryContentsAtPath:path];705 NSMutableArray *retArray = [[NSMutableArray alloc] initWithCapacity:[installedComponents count]];706 NSEnumerator *componentEnum = [installedComponents objectEnumerator];707 NSString *component;708 while ((component = [componentEnum nextObject])) {709 if ([[component pathExtension] isEqualToString:@"component"])710 [retArray addObject:component];711 }712 return [retArray autorelease];713 }714 715 - (NSDictionary *)componentInfoForComponent:(NSString *)component userInstalled:(BOOL)user716 {717 NSString *compName = component;718 if ([[component pathExtension] isEqualToString:@"component"])719 compName = [component stringByDeletingPathExtension];720 NSMutableDictionary *componentInfo = [[NSMutableDictionary alloc] initWithObjectsAndKeys:compName, @"name", NULL];721 NSBundle *componentBundle = [NSBundle bundleWithPath:[[self basePathForType:ComponentTypeQuickTime722 user:user] stringByAppendingPathComponent:component]];723 NSDictionary *infoDictionary = nil;724 if (componentBundle)725 infoDictionary = [componentBundle infoDictionary];726 if (infoDictionary && [infoDictionary objectForKey:BundleIdentifierKey]) {727 NSString *componentVersion = [infoDictionary objectForKey:BundleVersionKey];728 if (componentVersion)729 [componentInfo setObject:componentVersion forKey:@"version"];730 else731 [componentInfo setObject:@"Unknown" forKey:@"version"];732 [componentInfo setObject:(user ? @"User" : @"System") forKey:@"installType"];733 [componentInfo setObject:[self checkComponentStatusByBundleIdentifier:[componentBundle bundleIdentifier]] forKey:@"status"];734 [componentInfo setObject:[componentBundle bundleIdentifier] forKey:@"bundleID"];735 } else {736 [componentInfo setObject:@"Unknown" forKey:@"version"];737 [componentInfo setObject:(user ? @"User" : @"System") forKey:@"installType"];738 NSString *bundleIdent = [NSString stringWithFormat:PERIAN_NO_BUNDLE_ID_FORMAT,compName];739 [componentInfo setObject:[self checkComponentStatusByBundleIdentifier:bundleIdent] forKey:@"status"];740 [componentInfo setObject:bundleIdent forKey:@"bundleID"];741 }742 return [componentInfo autorelease];743 }744 745 - (NSArray *)installedComponents746 {747 NSArray *userComponents = [self installedComponentsForUser:YES];748 NSArray *systemComponents = [self installedComponentsForUser:NO];749 unsigned numComponents = [userComponents count] + [systemComponents count];750 NSMutableArray *components = [[NSMutableArray alloc] initWithCapacity:numComponents];751 NSEnumerator *compEnum = [userComponents objectEnumerator];752 NSString *compName;753 while ((compName = [compEnum nextObject]))754 [components addObject:[self componentInfoForComponent:compName userInstalled:YES]];755 756 compEnum = [systemComponents objectEnumerator];757 while ((compName = [compEnum nextObject]))758 [components addObject:[self componentInfoForComponent:compName userInstalled:NO]];759 return [components autorelease];760 }761 762 - (NSString *)checkComponentStatusByBundleIdentifier:(NSString *)bundleID763 {764 NSString *status = @"OK";765 NSEnumerator *infoEnum = [componentReplacementInfo objectEnumerator];766 NSDictionary *infoDict;767 while ((infoDict = [infoEnum nextObject])) {768 NSEnumerator *stringsEnum = [[infoDict objectForKey:ObsoletesKey] objectEnumerator];769 NSString *obsoletedID;770 while ((obsoletedID = [stringsEnum nextObject]))771 if ([obsoletedID isEqualToString:bundleID])772 status = [NSString stringWithFormat:@"Obsoleted by %@",[infoDict objectForKey:HumanReadableNameKey]];773 }774 return status;775 }776 777 697 #pragma mark Check Updates 778 698 - (IBAction)updateCheck:(id)sender … … 919 839 } 920 840 841 #pragma mark Component Manager 842 - (NSArray *)installedComponents 843 { 844 NSMutableArray *mComps = [[NSMutableArray alloc] init]; 845 846 NSMutableArray* allComps = [NSMutableArray array]; 847 848 [allComps addObjectsFromArray: GetComponentsInFolder(@"/Library/Components")]; 849 [allComps addObjectsFromArray: GetComponentsInFolder(@"/Library/QuickTime")]; 850 [allComps addObjectsFromArray: GetComponentsInFolder(@"~/Library/QuickTime")]; 851 [allComps addObjectsFromArray: GetComponentsInFolder(@"~/Library/Components")]; 852 853 [allComps addObjectsFromArray: GetComponentsInFolder(@"/Library/Components (Disabled)")]; 854 [allComps addObjectsFromArray: GetComponentsInFolder(@"/Library/QuickTime (Disabled)")]; 855 [allComps addObjectsFromArray: GetComponentsInFolder(@"~/Library/QuickTime (Disabled)")]; 856 [allComps addObjectsFromArray: GetComponentsInFolder(@"~/Library/Components (Disabled)")]; 857 858 unsigned x= 0; 859 for (x = 0; x < [allComps count]; x++) 860 { 861 NSString* comp = [allComps objectAtIndex:x]; 862 ECQTComponent* compobj = [ECQTComponent componentWithPath:comp]; 863 if (compobj && [compobj name]) 864 [mComps addObject:compobj]; 865 } 866 return [mComps autorelease]; 867 } 868 921 869 @end 870 871 NSArray* GetComponentsInFolder(NSString* folder) 872 { 873 folder = [folder stringByExpandingTildeInPath]; 874 NSFileManager* fm = [NSFileManager defaultManager]; 875 NSArray* contents = [fm directoryContentsAtPath:folder]; 876 NSMutableArray* newContents = [NSMutableArray array]; 877 unsigned x; 878 for (x = 0; x < [contents count]; x++) 879 { 880 NSString* comp = [contents objectAtIndex:x]; 881 882 [newContents addObject:[folder stringByAppendingPathComponent:comp]]; 883 } 884 return newContents; 885 } trunk/Perian.xcodeproj/project.pbxproj
r734 r792 75 75 11207C730C2F4A4E002A0FF0 /* ComponentInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 11207C720C2F4A4E002A0FF0 /* ComponentInfo.plist */; }; 76 76 112E0C820A6436BA00DB4C29 /* FFusionCodec.c in Sources */ = {isa = PBXBuildFile; fileRef = F560DF0003D61D0101ABA332 /* FFusionCodec.c */; }; 77 113077FF0D50139500ECDECC /* ECQTComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 113077FD0D50139500ECDECC /* ECQTComponent.m */; }; 77 78 113F589A0A6B091600509987 /* Codecprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = 113F58990A6B091600509987 /* Codecprintf.c */; }; 78 79 11629EE10B51E482006591C8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 11629EE00B51E482006591C8 /* main.m */; }; … … 440 441 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 441 442 11207C720C2F4A4E002A0FF0 /* ComponentInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; name = ComponentInfo.plist; path = Plists/ComponentInfo.plist; sourceTree = "<group>"; }; 443 113077FD0D50139500ECDECC /* ECQTComponent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ECQTComponent.m; sourceTree = "<group>"; }; 444 113077FE0D50139500ECDECC /* ECQTComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ECQTComponent.h; sourceTree = "<group>"; }; 442 445 113F58980A6B091600509987 /* Codecprintf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Codecprintf.h; sourceTree = "<group>"; }; 443 446 113F58990A6B091600509987 /* Codecprintf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Codecprintf.c; sourceTree = "<group>"; }; … … 1115 1118 isa = PBXGroup; 1116 1119 children = ( 1120 113077FD0D50139500ECDECC /* ECQTComponent.m */, 1121 113077FE0D50139500ECDECC /* ECQTComponent.h */, 1117 1122 83D1D6E00B4C81F200E09EC9 /* CPFPerianPrefPaneController.h */, 1118 1123 83D1D6E10B4C81F200E09EC9 /* CPFPerianPrefPaneController.m */, … … 1692 1697 files = ( 1693 1698 83D1D6E20B4C81F200E09EC9 /* CPFPerianPrefPaneController.m in Sources */, 1699 113077FF0D50139500ECDECC /* ECQTComponent.m in Sources */, 1694 1700 ); 1695 1701 runOnlyForDeploymentPostprocessing = 0; trunk/PerianPrefPane.nib/classes.nib
r685 r792 1 { 2 IBClasses = ( 3 { 4 ACTIONS = { 5 cancelDynRangeSheet = id; 6 installUninstall = id; 7 launchDonate = id; 8 launchForum = id; 9 launchWebsite = id; 10 saveDynRangeSheet = id; 11 set2ChannelModePopup = id; 12 setAC3DynamicRangePopup = id; 13 setAC3DynamicRangeSlider = id; 14 setAC3DynamicRangeValue = id; 15 setAutoUpdateCheck = id; 16 setLoadExternalSubtitles = id; 17 updateCheck = id; 18 }; 19 CLASS = CPFPerianPrefPaneController; 20 LANGUAGE = ObjC; 21 OUTLETS = { 22 "button_autoUpdateCheck" = NSButton; 23 "button_donate" = NSButton; 24 "button_forum" = NSButton; 25 "button_install" = NSButton; 26 "button_loadExternalSubtitles" = NSButton; 27 "button_updateCheck" = NSButton; 28 "button_website" = NSButton; 29 "popup_ac3DynamicRangeType" = NSPopUpButton; 30 "popup_outputMode" = NSPopUpButton; 31 "progress_install" = NSProgressIndicator; 32 "progress_updateCheck" = NSProgressIndicator; 33 "slider_ac3DynamicRangeSlider" = NSSlider; 34 "textField_ac3DynamicRangeValue" = NSTextField; 35 "textField_currentVersion" = NSTextField; 36 "textField_installStatus" = NSTextField; 37 "textView_about" = NSTextView; 38 "window_dynRangeSheet" = NSWindow; 39 }; 40 SUPERCLASS = NSPreferencePane; 41 }, 42 {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 43 { 44 CLASS = NSPreferencePane; 45 LANGUAGE = ObjC; 46 OUTLETS = { 47 "_firstKeyView" = NSView; 48 "_initialKeyView" = NSView; 49 "_lastKeyView" = NSView; 50 "_window" = NSWindow; 51 }; 52 SUPERCLASS = NSObject; 53 } 54 ); 55 IBVersion = 1; 56 } 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 <plist version="1.0"> 4 <dict> 5 <key>IBClasses</key> 6 <array> 7 <dict> 8 <key>CLASS</key> 9 <string>FirstResponder</string> 10 <key>LANGUAGE</key> 11 <string>ObjC</string> 12 <key>SUPERCLASS</key> 13 <string>NSObject</string> 14 </dict> 15 <dict> 16 <key>CLASS</key> 17 <string>NSObject</string> 18 <key>LANGUAGE</key> 19 <string>ObjC</string> 20 </dict> 21 <dict> 22 <key>ACTIONS</key> 23 <dict> 24 <key>cancelDynRangeSheet</key> 25 <string>id</string> 26 <key>installUninstall</key> 27 <string>id</string> 28 <key>launchDonate</key> 29 <string>id</string> 30 <key>launchForum</key> 31 <string>id</string> 32 <key>launchWebsite</key> 33 <string>id</string> 34 <key>saveDynRangeSheet</key> 35 <string>id</string> 36 <key>set2ChannelModePopup</key> 37 <string>id</string> 38 <key>setAC3DynamicRangePopup</key> 39 <string>id</string> 40 <key>setAC3DynamicRangeSlider</key> 41 <string>id</string> 42 <key>setAC3DynamicRangeValue</key> 43 <string>id</string> 44 <key>setAutoUpdateCheck</key> 45 <string>id</string> 46 <key>setLoadExternalSubtitles</key> 47 <string>id</string> 48 <key>updateCheck</key> 49 <string>id</string> 50 </dict> 51 <key>CLASS</key> 52 <string>CPFPerianPrefPaneController</string> 53 <key>LANGUAGE</key> 54 <string>ObjC</string> 55 <key>OUTLETS</key> 56 <dict> 57 <key>button_autoUpdateCheck</key> 58 <string>NSButton</string> 59 <key>button_donate</key> 60 <string>NSButton</string> 61 <key>button_forum</key> 62 <string>NSButton</string> 63 <key>button_install</key> 64 <string>NSButton</string> 65 <key>button_loadExternalSubtitles</key> 66 <string>NSButton</string> 67 <key>button_updateCheck</key> 68 <string>NSButton</string> 69 <key>button_website</key> 70 <string>NSButton</string> 71 <key>popup_ac3DynamicRangeType</key> 72 <string>NSPopUpButton</string> 73 <key>popup_outputMode</key> 74 <string>NSPopUpButton</string> 75 <key>progress_install</key> 76 <string>NSProgressIndicator</string> 77 <key>progress_updateCheck</key> 78 <string>NSProgressIndicator</string> 79 <key>slider_ac3DynamicRangeSlider</key> 80 <string>NSSlider</string> 81 <key>textField_ac3DynamicRangeValue</key> 82 <string>NSTextField</string> 83 <key>textField_currentVersion</key> 84 <string>NSTextField</string> 85 <key>textField_installStatus</key> 86 <string>NSTextField</string> 87 <key>textView_about</key> 88 <string>NSTextView</string> 89 <key>window_dynRangeSheet</key> 90 <string>NSWindow</string> 91 </dict> 92 <key>SUPERCLASS</key> 93 <string>NSPreferencePane</string> 94 </dict> 95 <dict> 96 <key>CLASS</key> 97 <string>NSPreferencePane</string> 98 <key>LANGUAGE</key> 99 <string>ObjC</string> 100 <key>OUTLETS</key> 101 <dict> 102 <key>_firstKeyView</key> 103 <string>NSView</string> 104 <key>_initialKeyView</key> 105 <string>NSView</string> 106 <key>_lastKeyView</key> 107 <string>NSView</string> 108 <key>_window</key> 109 <string>NSWindow</string> 110 </dict> 111 <key>SUPERCLASS</key> 112 <string>NSObject</string> 113 </dict> 114 </array> 115 <key>IBVersion</key> 116 <string>1</string> 117 </dict> 118 </plist> trunk/PerianPrefPane.nib/info.nib
r604 r792 1 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 3 <plist version="1.0"> 4 4 <dict> 5 <key>IBDocumentLocation</key>6 <string>112 62 356 240 0 0 1440 878 </string>7 5 <key>IBFramework Version</key> 8 <string>446.1</string> 6 <string>629</string> 7 <key>IBLastKnownRelativeProjectPath</key> 8 <string>../Perian.xcodeproj</string> 9 <key>IBOldestOS</key> 10 <integer>5</integer> 9 11 <key>IBOpenObjects</key> 10 12 <array> 11 <integer> 5</integer>13 <integer>133</integer> 12 14 </array> 13 15 <key>IBSystem Version</key> 14 <string>8R2218</string> 16 <string>9B18</string> 17 <key>targetFramework</key> 18 <string>IBCocoaFramework</string> 15 19 </dict> 16 20 </plist> trunk/Release/Read Me.rtf
r715 r792 1 {\rtf1\ mac\ansicpg10000\cocoartf824\cocoasubrtf4202 {\fonttbl\f0\fswiss\fcharset 77 Helvetica-Bold;\f1\fswiss\fcharset77Helvetica;}1 {\rtf1\ansi\ansicpg1252\cocoartf949 2 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 3 {\colortbl;\red255\green255\blue255;} 4 \margl1440\margr1440\vieww16040\viewh15820\viewkind05 4 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural 6 5 7 6 \f0\b\fs24 \cf0 About 8 \ f1\b0 \7 \b0 \ 9 8 Perian aims at providing a single package to provide all your playback needs. It is a collection of QuickTime components incorporating several libraries:\ 10 \' a5 libavcodec, from the ffmpeg project, along with code from the old FFusion component:\11 \' a5 MS-MPEG4 v1 & v2\12 \' a5 DivX\13 \' a5 3ivX\14 \' a5 H.264\15 \' a5 Flash Video\16 \' a5 Flash Screen Video\17 \' a5 VP6\18 \' a5 H263I\19 \' a5 VP3\20 \' a5 HuffYUV\21 \' a5 ffvhuff\22 \' a5 MPEG-1 & 2 video\23 \' a5 FRAPS\24 \' a5 Windows Media Audio v1 & v2\25 \' a5 Flash ADPCM\26 \' a5 Xiph Vorbis (in Matroska)\27 \' a5 MPEG Layer II Audio\28 \' a5 libavformat, from the ffmpeg project. along with AVIImporter.component:\29 \' a5 AVI file format\30 \' a5 FLV file format\31 \' a5 libmatroska, along with matroska-qt.component:\32 \' a5 MKV file format\33 \' a5 Subtitle parsing\34 \' a5 SSA file format\35 \' a5 SRT file format\36 \' a5 liba52, via A52Codec\37 \' a5 AC3 audio\9 \'95 libavcodec, from the ffmpeg project, along with code from the old FFusion component:\ 10 \'95 MS-MPEG4 v1 & v2\ 11 \'95 DivX\ 12 \'95 3ivX\ 13 \'95 H.264\ 14 \'95 Flash Video\ 15 \'95 Flash Screen Video\ 16 \'95 VP6\ 17 \'95 H263I\ 18 \'95 VP3\ 19 \'95 HuffYUV\ 20 \'95 ffvhuff\ 21 \'95 MPEG-1 & 2 video\ 22 \'95 FRAPS\ 23 \'95 Windows Media Audio v1 & v2\ 24 \'95 Flash ADPCM\ 25 \'95 Xiph Vorbis (in Matroska)\ 26 \'95 MPEG Layer II Audio\ 27 \'95 libavformat, from the ffmpeg project. along with AVIImporter.component:\ 28 \'95 AVI file format\ 29 \'95 FLV file format\ 30 \'95 libmatroska, along with matroska-qt.component:\ 31 \'95 MKV file format\ 32 \'95 Subtitle parsing\ 33 \'95 SSA file format\ 34 \'95 SRT file format\ 35 \'95 liba52, via A52Codec\ 36 \'95 AC3 audio\ 38 37 \ 39 38 The code is available under the LGPL. The project site is located at <http://trac.perian.org/> and the project subversion repository is located at <http://svn.perian.org/>.\ … … 41 40 \ 42 41 43 \ f0\b Easy Install44 \ f1\b0 \42 \b Easy Install 43 \b0 \ 45 44 To use Perian, open the disk image, and double click on the Perian.prefPane icon. It will automatically install and update all of its components.\ 46 45 \ 47 46 48 \ f0\b The Perian Team49 \ f1\b0 \47 \b The Perian Team 48 \b0 \ 50 49 Graham Booker - Dev and hosting\ 51 50 David Conrad - Dev\ … … 56 55 \ 57 56 58 \ f0\b Thanks to59 \ f1\b0 \60 J\' 8er\'99me Cornet and his FFusion project for giving me the idea and code to start from Christoph N\'8ageli's AVI Importer from his XviD component, which allowed us to leverage libavformat.\57 \b Thanks to 58 \b0 \ 59 J\'e9r\'f4me Cornet and his FFusion project for giving me the idea and code to start from Christoph N\'e4geli's AVI Importer from his XviD component, which allowed us to leverage libavformat.\ 61 60 FFMPEG project for providing such a rich library.\ 62 The Mozilla Foundation and Dag \' 81gren for the universal charset detector.\61 The Mozilla Foundation and Dag \'c5gren for the universal charset detector.\ 63 62 Adrian Thurston for the Ragel parser generator.\ 64 63 Matroska for their library.\ … … 66 65 \cf0 Bryan Bortz for the icon.\ 67 66 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural 68 \cf0 \ 69 All the people that put up with my insane requests for help and free testing, notably MartianSteve from #macsb for the first ICBM test, and Graham Booker for joining up with me and fixing the build every time I add a feature and then run off somewhere like the overcommitted madman I am.\ 70 \ 67 \cf0 Ken Aspeslagh for releasing the source to his QuickTime Component Manager (http://macdaddyworld.com/quicktime-component-manager/) which gives us most of the smarts for the component manager tab.\ 71 68 \ 72 69 \ 73 70 74 \ f0\b Licenses\71 \b Licenses\ 75 72 \ 76 73 77 \ f1\b0 GNU LESSER GENERAL PUBLIC LICENSE\74 \b0 GNU LESSER GENERAL PUBLIC LICENSE\ 78 75 Version 2.1, February 1999\ 79 76 \
