async StartABRMezzanineJobs({libraryId, objectId, offeringKey="default", access={}}) {
    const mezzanineMetadata = await this.ContentObjectMetadata({
      libraryId,
      objectId,
      metadataSubtree: UrlJoin("abr_mezzanine", "offerings")
    });

    const masterHash = mezzanineMetadata.default.prod_master_hash;

    // get file list from master
    // ** temporary workaround for permissions issue
    const masterFileData = await this.ContentObjectMetadata({
      versionHash: masterHash,
      metadataSubtree: "files"
    });


    const prepSpecs = mezzanineMetadata[offeringKey].mez_prep_specs || [];

    /*
    // Retrieve all masters associated with this offering
    const masterVersionHashes = prepSpecs.map(spec =>
      (spec.source_streams || []).map(stream => stream.master_hash)
    )
      .flat()
      .filter(hash => hash)
      .filter((v, i, a) => a.indexOf(v) === i);
    */

    const masterVersionHashes = [masterHash];

    // Retrieve authorization tokens for all masters and the mezzanine

    let authorizationTokens = await Promise.all(
      masterVersionHashes.map(async versionHash => await this.authClient.AuthorizationToken({versionHash}))
    );

    authorizationTokens = [
      await this.authClient.AuthorizationToken({libraryId, objectId, update: true}),
      ...authorizationTokens
    ];

    const headers = {
      Authorization: authorizationTokens.map(token => `Bearer ${token}`).join(",")
    };

    let accessParameter;
    if(access && Object.keys(access).length > 0) {
      const {region, bucket, accessKey, secret} = access;
      accessParameter = [
        {
          path_matchers: [".*"],
          remote_access: {
            protocol: "s3",
            platform: "aws",
            path: bucket + "/",
            storage_endpoint: {
              region
            },
            cloud_credentials: {
              access_key_id: accessKey,
              secret_access_key: secret
            }
          }
        }
      ];
    }

    const {write_token} = await this.EditContentObject({libraryId, objectId});

    const {data, errors, warnings, logs} = await this.CallBitcodeMethod({
      libraryId,
      objectId,
      writeToken: write_token,
      headers,
      method: UrlJoin("media", "abr_mezzanine", "prep_start"),
      constant: false,
      body: {
        access: accessParameter,
        offering_key: offeringKey,
        job_indexes: [...Array(prepSpecs.length).keys()],
        production_master_files: masterFileData
      }
    });

    return {
      writeToken: write_token,
      data,
      logs: logs || [],
      warnings: warnings || [],
      errors: errors || []
    };
  }
/**
   * Start any incomplete jobs on the specified mezzanine
   *
   * @methodGroup Media
   * @namedParams
   * @param {string} libraryId - ID of the mezzanine library
   * @param {string} objectId - ID of the mezzanine object
   * @param {string=} offeringKey=default - The offering to process
   * @param {Object=} access - (S3) Region, bucket, access key and secret for S3 - Required if any files in the masters are S3 references
   * - Format: {region, bucket, accessKey, secret}
   *
   * @return {Promise<Object>} - A write token for the mezzanine object, as well as any logs, warnings and errors from the job initialization
   */


@return {Promise} - A write token for the mezzanine object, as well as any logs, warnings and errors from the job initialization
@return { Promise } - A write token for the mezzanine object as well as any logs warnings and errors from the job initialization
async StartABRMezzanineJobs({libraryId, objectId, offeringKey="default", access={}}) {
    const mezzanineMetadata = await this.ContentObjectMetadata({
      libraryId,
      objectId,
      metadataSubtree: UrlJoin("abr_mezzanine", "offerings")
    });
    const masterHash = mezzanineMetadata.default.prod_master_hash;
    const masterFileData = await this.ContentObjectMetadata({
      versionHash: masterHash,
      metadataSubtree: "files"
    });
    const prepSpecs = mezzanineMetadata[offeringKey].mez_prep_specs || [];
    const masterVersionHashes = [masterHash];
    let authorizationTokens = await Promise.all(
      masterVersionHashes.map(async versionHash => await this.authClient.AuthorizationToken({versionHash}))
    );
    authorizationTokens = [
      await this.authClient.AuthorizationToken({libraryId, objectId, update: true}),
      ...authorizationTokens
    ];
    const headers = {
      Authorization: authorizationTokens.map(token => `Bearer ${token}`).join(",")
    };
    let accessParameter;
    if(access && Object.keys(access).length > 0) {
      const {region, bucket, accessKey, secret} = access;
      accessParameter = [
        {
          path_matchers: [".*"],
          remote_access: {
            protocol: "s3",
            platform: "aws",
            path: bucket + "/",
            storage_endpoint: {
              region
            },
            cloud_credentials: {
              access_key_id: accessKey,
              secret_access_key: secret
            }
          }
        }
      ];
    }
    const {write_token} = await this.EditContentObject({libraryId, objectId});
    const {data, errors, warnings, logs} = await this.CallBitcodeMethod({
      libraryId,
      objectId,
      writeToken: write_token,
      headers,
      method: UrlJoin("media", "abr_mezzanine", "prep_start"),
      constant: false,
      body: {
        access: accessParameter,
        offering_key: offeringKey,
        job_indexes: [...Array(prepSpecs.length).keys()],
        production_master_files: masterFileData
      }
    });
    return {
      writeToken: write_token,
      data,
      logs: logs || [],
      warnings: warnings || [],
      errors: errors || []
    };
  }
async StartABRMezzanineJobs ( { libraryId , objectId , offeringKey = "default" , access = { } } ) { const mezzanineMetadata = await this . ContentObjectMetadata ( { libraryId , objectId , metadataSubtree : UrlJoin ( "abr_mezzanine" , "offerings" ) } ) ; const masterHash = mezzanineMetadata . default . prod_master_hash ; const masterFileData = await this . ContentObjectMetadata ( { versionHash : masterHash , metadataSubtree : "files" } ) ; const prepSpecs = mezzanineMetadata [ offeringKey ] . mez_prep_specs || [ ] ; const masterVersionHashes = [ masterHash ] ; let authorizationTokens = await Promise . all ( masterVersionHashes . map ( async versionHash => await this . authClient . AuthorizationToken ( { versionHash } ) ) ) ; authorizationTokens = [ await this . authClient . AuthorizationToken ( { libraryId , objectId , update : true } ) , ... authorizationTokens ] ; const headers = { Authorization : authorizationTokens . map ( token => ` ${ token } ` ) . join ( "," ) } ; let accessParameter ; if ( access && Object . keys ( access ) . length > 0 ) { const { region , bucket , accessKey , secret } = access ; accessParameter = [ { path_matchers : [ ".*" ] , remote_access : { protocol : "s3" , platform : "aws" , path : bucket + "/" , storage_endpoint : { region } , cloud_credentials : { access_key_id : accessKey , secret_access_key : secret } } } ] ; } const { write_token } = await this . EditContentObject ( { libraryId , objectId } ) ; const { data , errors , warnings , logs } = await this . CallBitcodeMethod ( { libraryId , objectId , writeToken : write_token , headers , method : UrlJoin ( "media" , "abr_mezzanine" , "prep_start" ) , constant : false , body : { access : accessParameter , offering_key : offeringKey , job_indexes : [ ... Array ( prepSpecs . length ) . keys ( ) ] , production_master_files : masterFileData } } ) ; return { writeToken : write_token , data , logs : logs || [ ] , warnings : warnings || [ ] , errors : errors || [ ] } ; }
Start any incomplete jobs on the specified mezzanine
 @methodGroup Media
 @namedParams
 @param {string} libraryId - ID of the mezzanine library
 @param {string} objectId - ID of the mezzanine object
 @param {string=} offeringKey=default - The offering to process
 @param {Object=} access - (S3) Region, bucket, access key and secret for S3 - Required if any files in the masters are S3 references
 - Format: {region, bucket, accessKey, secret}
Start any incomplete jobs on the specified mezzanine @methodGroup Media @namedParams @param { string } libraryId - ID of the mezzanine library @param { string } objectId - ID of the mezzanine object @param { string = } offeringKey = default - The offering to process @param { Object = } access - ( S3 ) Region bucket access key and secret for S3 - Required if any files in the masters are S3 references - Format : { region bucket accessKey secret }
// get file list from master // ** temporary workaround for permissions issue /*
    // Retrieve all masters associated with this offering
    const masterVersionHashes = prepSpecs.map(spec =>
      (spec.source_streams || []).map(stream => stream.master_hash)
    )
      .flat()
      .filter(hash => hash)
      .filter((v, i, a) => a.indexOf(v) === i);
    */ // Retrieve authorization tokens for all masters and the mezzanine